diff --git a/Commands/Completion: Ruby (rcodetools).tmCommand b/Commands/Completion: Ruby (rcodetools).tmCommand index b90636a..1c5b5d1 100644 --- a/Commands/Completion: Ruby (rcodetools).tmCommand +++ b/Commands/Completion: Ruby (rcodetools).tmCommand @@ -1,11 +1,11 @@ - + beforeRunningCommand nop command - #!/usr/bin/env ruby -w + #!/usr/bin/env ruby require "#{ENV["TM_SUPPORT_PATH"]}/lib/exit_codes" require "#{ENV["TM_SUPPORT_PATH"]}/lib/ui" diff --git a/Support/vendor/rcodetools-old/CHANGES b/Support/vendor/rcodetools-old/CHANGES new file mode 100644 index 0000000..57056ba --- /dev/null +++ b/Support/vendor/rcodetools-old/CHANGES @@ -0,0 +1,46 @@ +rcodetools history +================== +User-visible changes since 0.5.0 +-------------------------------- +* "test-driven completion" (TDC) support for Emacs and vim (see README.TDC) +* --test (-t), --filename options for rct-complete and rct-doc, allowing to + specify the test to be run for 100% accurate completion/documentation in the + corresponding implementation +* ruby-toggle-file: finds the test file corresponding to a given + implementation and vice versa +* rct-fork, rct-fork-client: allow to eliminate the overhead due to library + loading (esp. useful for Rails) +* rbtest: executes unit tests in a single Ruby script +* --fork, --rbtest, --detect-rbtest supported by several commands +* xmpfilter's --spec now autodetects the RSpec version and generates + specifications with the appropriate syntax + +User-visible changes since 0.4.1 +-------------------------------- +* --dev: adds project directories to $: +* --completion-class-info: list completion candidates and class info +* display completion candidates with description, both in emacs + and vim (using the menu+preview window). + +User-visible changes since 0.4.0 +-------------------------------- +* rct-meth-args: implemented -I +* many bug fixes + +xmpfilter was integrated into rcodetools as of 0.4.0. + +xmpfilter history +================= +User-visible changes since 0.3.1 (2006-10-17) +* implemented --debug +* --[no]-warnings +* --cd working_dir +* --rails +* --no-poetry +* more intelligent assertions: try to find which local variables hold the + values compared against in assertions/expectations +* editor-independent completion (-C, --completion-emacs, --completion-vim) +* quick method/class reference with -D (--refe, --ri*) + +User-visible changes since 0.3.0 (2006-10-16) +* xmpfilter.rb --spec works on win32 too diff --git a/Support/vendor/rcodetools-old/README b/Support/vendor/rcodetools-old/README new file mode 100644 index 0000000..38434ec --- /dev/null +++ b/Support/vendor/rcodetools-old/README @@ -0,0 +1,98 @@ + + rcodetools http://eigenclass.org/hiki.rb?rcodetools + Copyright (c) 2005-2007 Mauricio Fernandez http://eigenclass.org + Copyright (c) 2006-2007 rubikitch http://www.rubyist.net/~rubikitch/ +Use and distribution subject to the terms of the Ruby license. + += Overview +rcodetools is a collection of Ruby code manipulation tools. +It includes xmpfilter and editor-independent Ruby development helper tools, +as well as emacs and vim interfaces. + +Currently, rcodetools comprises: +* xmpfilter: Automagic Test::Unit assertions/RSpec expectations and code annotations +* rct-complete: Accurate method/class/constant etc. completions +* rct-doc: Document browsing and code navigator +* rct-meth-args: Precise method info (meta-prog. aware) and TAGS generation +* rct-fork: Pre-load heavy library(Rails etc) and speed up rct-complete/rct-doc (server) +* rct-fork-client: Run Ruby programs from state the rct-fork server has +* ruby-toggle-file: Toggle implementation file and test file +* rbtest: Embedded Test::Unit for small scripts + +See also README.xmpfilter. + +Originally rct-complete and rct-doc were subcommands of xmpfilter. +Actually they use xmpfilter's code heavily. +But the relationship between xmpfilter (annotation) and completion/doc is not +intuitive, so I (rubikitch) split it into separate executables. + += Usage +xmpfilter, rct-complete and rct-doc take its input from stdin and write to +stdout. They can run in several modes; see + xmpfilter -h + rct-complete -h + rct-doc -h + rct-meth-args -h + rct-fork -h + rct-fork-client -h + ruby-toggle-file -h + rbtest -h +README.emacs and README.vim describe how to use rcodetools from your editor. + += Accurate Completion Internal and Caveat +rct-complete and rct-doc use xmpfilter engine, ie they get runtime information by executing code. +In Ruby (dynamic languages), type of any expressions except literals cannot be known without actually executing code. +Moreover Ruby has open classes and singleton methods. +Rcodetools asks `ruby' run-time informations, so we can get very accurate informations. +Completion and document browsing are essentially identical operations, +they both need the object value in question. +Therefore we discuss completion. + +rct-complete does: +(1) replaces target line with completion magic + (it calculates methods the target object has). +(2) executes modified script. +(3) once the control reaches completion magic, modified script exits. +(4) outputs in specified format. (list candidates, EmacsLisp...) + +But this methodology has two big drawbacks, side-effects and inability to get any informations of uncovered code! + +An extreme side-effect example: + File.unlink a_file + File. <- + +If you call rct-complete, it removes a_file (sends a mail, accesses DB ...). +So you must be careful to use, especially at TOPLEVEL. +I (rubikitch) often experiment at TOPLEVEL with rcodetools, I NEVER use irb(sh) since rcodetools! + +An uncovered code example: + def foo + 1. <- + end + +If the code does not call foo, we cannot do any completions. + +Useless eh? But we already have a way to elude the drawbacks, test scripts (unit tests)! +Test scripts are self-enclosed and expected to be executed, so side-effects are not problem. +Moreover tests call methods we write. +Because Ruby's Test::Unit has an ability to test only one test method, we can do lightning-fast completion. +Let's call it Test-Driven Completion (TDC). + +To support TDC, rct-complete has -t option. +With -t, it concatenate modified script and test/unit code. +If the control does not reach target line, test/unit code calls the line. + +How do we select test script and test method? +The editor selects recently selected buffer of test script as test script of TDC, +because the test-infected tend to go and return between test script and implementation script. +It considers files matching /test.*\.rb/ as test script. +It selects test method at the cursor position. + +TDC adds roles of test scripts. +Enjoy TDC magic! + +See also README.TDC. + + += License +rcodetools is licensed under the same terms as Ruby. diff --git a/Support/vendor/rcodetools-old/README.emacs b/Support/vendor/rcodetools-old/README.emacs new file mode 100644 index 0000000..c6307c2 --- /dev/null +++ b/Support/vendor/rcodetools-old/README.emacs @@ -0,0 +1,54 @@ + +rcodetools.el allows you to run rcodetools on a buffer. + +To eval the sexp, type C-e C-x C-e; `end-of-line' and `eval-last-sexp'. + +installation +============ + +If you use RI document feature, you must install ri-emacs first. + http://rubyforge.org/projects/ri-emacs/ + +If you feel RI and ri-emacs.rb startup is SLOW, you want to install FastRI. +FastRI offers ri-emacs compatible layer, so you can use it with ri-ruby.el. + http://eigenclass.org/hiki.rb?fastri + +Copy rcodetools.el to the appropriate directory, which is in load-path. +Then require it. + (require 'rcodetools) + +If you use icicles copy icicles-rcodetools.el too. +Then require it. + (require 'icicles-rcodetools) +It provides wonderful `help on candidate' feature, RI document on each candidate during completion. +I'm addicted to icicles! + http://www.emacswiki.org/cgi-bin/wiki/Icicles + +xmpfilter on buffer +=================== + +# [EVAL IT] (describe-function 'xmp) + +If you want to add => marks, call comment-dwim twice. + +# [EVAL IT] (describe-function 'comment-dwim) + +method/class/constant completion +================================ + +# [EVAL IT] (describe-function 'rct-complete-symbol) + +If you use icicles-rcodetools, you can browse RI document for selected candidate +by typing C-M-RET. It is wonderful icicles feature!! + +show RI document / jump to the definition +========================================= + +# [EVAL IT] (describe-function 'rct-ri) + +By default rct-ri asks for a TAGS file, which is generated by tag generator like rtags. +If there is a TAGS file, this command jumps to the definition of current method. +If use do not use this feature, evaluate: + (setq rct-find-tag-if-available nil) + +# [EVAL IT] (describe-variable 'rct-find-tag-if-available) diff --git a/Support/vendor/rcodetools-old/README.method_analysis b/Support/vendor/rcodetools-old/README.method_analysis new file mode 100644 index 0000000..53a482d --- /dev/null +++ b/Support/vendor/rcodetools-old/README.method_analysis @@ -0,0 +1,13 @@ + +method_analyzer.rb can be used to gather precise information about the exact +methods called in your code, allowing you to explore it better with rct-doc +(see README.emacs and README.vim for more information). This requires high +code coverage, since it can only record such data when the code is executed. + +rct-meth-args can be used to generate fairly complete TAGS files. It operates +by loading the specified files and tracking method definitions; therefore, it +is meta-programming aware, unlike other implementations. + +You can use them conveniently by adding the code shown in +Rakefile.method_analysis to your Rakefile. + diff --git a/Support/vendor/rcodetools-old/README.vim b/Support/vendor/rcodetools-old/README.vim new file mode 100644 index 0000000..ea7c7c5 --- /dev/null +++ b/Support/vendor/rcodetools-old/README.vim @@ -0,0 +1,111 @@ + +Copy rcodetools.vim to your plugin directory (typically $HOME/.vim/plugin) in +order to enable accurate code completion, quick RI execution and exact tag +jumping. + +Switching between implementation and test files +=============================================== +The t binding (by default \t) will call ruby-toggle-file to +switch from test to implementation and vice versa. Moreover, when you switch +from the test to the implementation, rcodetools will remember which test +you were editing (based on the cursor position), and call it as needed for +advanced code completion or precise RI documentation, as documented below. + +The actual binding can be changed in your .vimrc as follows: + let g:RCT_toggle_binding="" " use ^X^T to go test <=> implementation + +Code completion +=============== +rcodetools.vim redefines user-defined completion for Ruby programs, so you can +use the intelligent, 100%-accurate completion with in insert mode. +Note that this runs the code to obtain the exact candidate list. + +If you've set completeopt to menu,preview then rcodetools.vim can display +information about the completion candidates. The menu will show the synopsis +as given in the RI documentation, and the preview window will contain the full +RI documentation. + +This functionality relies on fri for quick lookups. It can be enabled by setting + + let g:rct_completion_use_fri = 1 " 0 by default (disabled) + +in your .vimrc (don't forget to run fastri-server too). +Obtaining the documentation for many candidates can be slow, so you can set +the threshold above which additional documentation will not be shown with + + " 20 by default, about a couple secs max wait on a normal machine + let g:rct_completion_info_max_len = 20 + +Quick RI documentation and exact tag jumping +============================================ +When you're editing a Ruby file, will jump to the definition of the +chosen element if found in the TAGS file; otherwise, it will call RI and show +the documentation in a new window. +You can specify the RI executable to use by adding something like + let g:RCT_ri_cmd = "ri -T -f plain " +to your .vimrc. (rcodetools.vim also honors b:RCT_RI_cmd and w:RCT_RI_cmd if set). +By default, "fri -f plain " will be used. fri (FastRI) is an improved RI +documentation browser, which features more intelligent search modes, gem +integration, vastly better performance... You can find it at +http://eigenclass.org/hiki.rb?fastri and it's also available in gem format +gem install fastri + +If you want to call RI for the word the cursor is on (instead of jumping to +the definition if found), you can use this binding: + r (\r by default if you haven't changed your localleader) +You can specify another binding in your .vimrc as follows: + let g:RCT_ri_binding="" " use ^X^R to call vim on current word + +Using xmpfilter +=============== +xmpfilter takes code from stdin and outputs to stdout so you can filter +your code with ! as usual. + +If you use xmpfilter often, you might want to use mappings like the +following, which allow you to: +* add annotations +* expand assertions +* insert/remove # => markers + + + +" plain annotations +map !xmpfilter -a +nmap V +imap a + +" Test::Unit assertions; use -s to generate RSpec expectations instead +map !xmpfilter -u +nmap V +imap a + +" Annotate the full buffer +" I actually prefer ggVG to %; it's a sort of poor man's visual bell +nmap mzggVG!xmpfilter -a'z +imap + +" assertions +nmap mzggVG!xmpfilter -u'z +imap a + +" Add # => markers +vmap !xmpfilter -m +nmap V +imap a + +" Remove # => markers +vmap ms:call RemoveRubyEval() +nmap V +imap a + + +function! RemoveRubyEval() range + let begv = a:firstline + let endv = a:lastline + normal Hmt + set lz + execute ":" . begv . "," . endv . 's/\s*# \(=>\|!!\).*$//e' + normal 'tzt`s + set nolz + redraw +endfunction diff --git a/Support/vendor/rcodetools-old/README.xmpfilter b/Support/vendor/rcodetools-old/README.xmpfilter new file mode 100644 index 0000000..2ed67cb --- /dev/null +++ b/Support/vendor/rcodetools-old/README.xmpfilter @@ -0,0 +1,202 @@ + +xmpfilter http://eigenclass.org/hiki.rb?xmpfilter +Copyright (c) 2005-2006 Mauricio Fernandez http://eigenclass.org +Use and distribution subject to the terms of the Ruby license. + +Overview +======== +xmpfilter is a small tool that can be used to +* generate Test::Unit assertions and RSpec expectations semi-automatically +* annotate source code with intermediate results (a bit like irb + --simple-prompt but only for the lines explicitly marked with # =>) + Very useful for example code (such as postings to ruby-talk). + +Usage +===== +xmpfilter takes its input from stdin and writes to stdout. It can run in +several modes (annotation, Test::Unit assertion expansion, RSpec expectation +generation, marker insertion); see + xmpfilter -h +README.emacs and README.vim describe how to use xmpfilter from your editor. + +Example: code annotation +======================== +Just add "# =>" markers to the lines whose values you want to be shown: + + a, b = "foo", "baz" + a + b # => + a.size # => + +will be expanded to (in one keypress in a decent editor, see README.emacs and +README.vim) + + a, b = "foo", "baz" + a + b # => "foobaz" + a.size # => 3 + +This saves much cut&pasting when you're posting to ruby-talk/ruby-core (I use +it all the time). + +Example: assertion generation +============================= + +xmpfilter can generate assertions based on the current behavior of the code +to be tested (iow. the current behavior is assumed to be correct and is used +to generate assertions which won't be modified by further runs of +xmpfilter), making it quite useful for regression testing. + +Imagine you have a ComplexClass you want to test. You might start with + + class TestComplexClass < Test::Unit::TestCase + def setup; @o = ComplexClass.new("foo", false) end + end + +and then want to add some tests: + + def test_insertion + @o.insert "bar" + @o.insert "baz" + # ... assertions here + end + +At this point, you want to add several assertions to verify that the values +returned by @o.size, @o.last, @o.first, @o.complex_computation and @o.last(2) +are correct. You can just write the following and feed the file to +xmpfilter in -u mode (the # => markers can also be inserted by +xmpfilter, see README.vim for more information: + + def test_insertion + @o.insert "bar" + @o.insert "baz" + @o.size # => + @o.last # => + @o.first # => + @o.complex_computation # => + @o.last(2) # => + end + +xmpfilter will run the test and remember what happened in each marked line, +and then rewrite the code so that it looks for instance like + + def test_insertion + @o.insert "bar" + @o.insert "baz" + assert_equal(2, @o.size) + assert_equal("baz", @o.last) + assert_equal("bar", @o.first) + assert_in_delta(3.14159265358979, @o.complex_computation, 0.0001) + assert_equal(["baz", "bar"], @o.last(2)) + end + +As you can see, it can save some typing. + +You can edit the generated assertions as you want: xmpfilter will not +modify lines without the "# =>" marker. xmpfilter can be used repeatedly as +you add more assertions. Imagine you want to verify that @o.last(3) raises an +ArgumentError. You can simply add one line marked with # => : + + ... + assert_in_delta(3.14159265358979, @o.complex_computation, 0.0001) + assert_equal(["baz", "bar"], @o.last(2)) + @o.last(3) # => + end + +and have it expanded by xmpfilter: + + ... + assert_in_delta(3.14159265358979, @o.complex_computation, 0.0001) + assert_equal(["baz", "bar"], @o.last(2)) + assert_raise(ArgumentError){ @o.last(3) } + end + + +Example: RSpec expectations +=========================== +Here's some code before and after filtering it with xmpfilter: + + class X + Y = Struct.new(:a) + def foo(b); b ? Y.new(2) : 2 end + def bar; raise "No good" end + def baz; nil end + def fubar(x); x ** 2.0 + 1 end + def babar; [1,2] end + A = 1 + A = 1 + end + + context "Testing xmpfilter's expectation expansion" do + setup do + @o = X.new + end + + specify "Should expand should_equal expectations" do + @o.foo(true) # => + @o.foo(true).a # => + @o.foo(false) # => + end + + specify "Should expand should_raise expectations" do + @o.bar # => + end + + specify "Should expand should_be_nil expectations" do + @o.baz # => + end + + specify "Should expand correct expectations for complex values" do + @o.babar # => + end + + specify "Should expand should_be_close expectations" do + @o.fubar(10) # => + end + end + + +after piping it to xmpfilter -s: + + class X + Y = Struct.new(:a) + def foo(b); b ? Y.new(2) : 2 end + def bar; raise "No good" end + def baz; nil end + def fubar(x); x ** 2.0 + 1 end + def babar; [1,2] end + A = 1 + A = 1 # !> already initialized constant A + end + + context "Testing xmpfilter's expectation expansion" do + setup do + @o = X.new + end + + specify "Should expand should_equal expectations" do + (@o.foo(true)).should_be_a_kind_of X::Y + (@o.foo(true).inspect).should_equal "#" + (@o.foo(true).a).should_equal 2 + (@o.foo(false)).should_equal 2 + end + + specify "Should expand should_raise expectations" do + lambda{(@o.bar)}.should_raise RuntimeError + end + + specify "Should expand should_be_nil expectations" do + (@o.baz).should_be_nil + end + + specify "Should expand correct expectations for complex values" do + (@o.babar).should_equal [1, 2] + end + + specify "Should expand should_be_close expectations" do + (@o.fubar(10)).should_be_close(101.0, 0.0001) + end + end + + +License +======= +xmpfilter is licensed under the same terms as Ruby. diff --git a/Support/vendor/rcodetools-old/Rakefile b/Support/vendor/rcodetools-old/Rakefile new file mode 100644 index 0000000..190668f --- /dev/null +++ b/Support/vendor/rcodetools-old/Rakefile @@ -0,0 +1,143 @@ + +PKG_REVISION = ".0" + +$:.unshift "lib" if File.directory? "lib" +require 'rcodetools/xmpfilter' +require 'rake/testtask' +include Rcodetools +RCT_VERSION = XMPFilter::VERSION + +desc "Run the unit tests in pure-Ruby mode ." +Rake::TestTask.new(:test) do |t| + t.libs << "ext/rcovrt" + t.test_files = FileList['test/test*.rb'] + t.verbose = true +end + +require 'rcov/rcovtask' +desc "Run rcov." +Rcov::RcovTask.new do |t| + t.rcov_opts << "--xrefs" # comment to disable cross-references + t.test_files = FileList['test/test_*.rb'].to_a - ["test/test_functional.rb"] + t.verbose = true +end + +desc "Save current coverage state for later comparisons." +Rcov::RcovTask.new(:rcovsave) do |t| + t.rcov_opts << "--save" + t.test_files = FileList['test/test_*.rb'].to_a - ["test/test_functional.rb"] + t.verbose = true +end + +task :default => :test + +## test data file dependency +basetestfiles = [] +copy = lambda do |t| + cp t.prerequisites.first, t.name +end + +# DO NOT EDIT!! EDITABLE +[ ["test/data/rspec_poetry-input.rb", "test/data/rspec-input.rb"], + ["test/data/unit_test_poetry-input.rb", "test/data/unit_test-input.rb"], + ["test/data/completion_emacs-input.rb", "test/data/completion-input.rb"], + ["test/data/unit_test_detect_rbtest-input.rb", "test/data/unit_test-input.rb"], + ["test/data/unit_test_detect_rbtest-output.rb", "test/data/unit_test-output.rb"], + ["test/data/unit_test_detect_rbtest2-input.rb", "test/data/unit_test_rbtest-input.rb"], + ["test/data/unit_test_detect_rbtest2-output.rb", "test/data/unit_test_rbtest-output.rb"], + ["test/data/completion_detect_rbtest-input.rb", "test/data/completion_rbtest-input.rb"], + ["test/data/completion_detect_rbtest-output.rb", "test/data/completion_rbtest-output.rb"], + ["test/data/completion_detect_rbtest2-input.rb", "test/data/completion-input.rb"], + ["test/data/completion_detect_rbtest2-output.rb", "test/data/completion-output.rb"], + ["test/data/doc_detect_rbtest-input.rb", "test/data/doc-input.rb"], + ["test/data/doc_detect_rbtest-output.rb", "test/data/doc-output.rb"], + ["test/data/doc_detect_rbtest2-input.rb", "test/data/doc_rbtest-input.rb"], + ["test/data/doc_detect_rbtest2-output.rb", "test/data/doc_rbtest-output.rb"], + +].each do |outfile, infile| + basetestfiles << outfile + file(outfile => infile, ©) +end +for test in %w[refe ri ri_emacs ri_vim] + outfile = "test/data/#{test}-input.rb" + basetestfiles << outfile + file(outfile => "test/data/doc-input.rb", ©) +end +task :base_update => basetestfiles +task :test => :base_update +task :rcov => :base_update + +#{{{ Package tasks +PKG_FILES = FileList[ +"bin/rct-complete", "bin/rct-doc", "bin/xmpfilter", "bin/rct-meth-args", +"lib/**/*.rb", +"CHANGES", "rcodetools.*", "icicles-rcodetools.el", "README", "README.*", "THANKS", +"Rakefile", "Rakefile.method_analysis", +"setup.rb", +"test/**/*.rb", +] + +begin + require 'rake/gempackagetask' + Spec = Gem::Specification.new do |s| + s.name = "rcodetools" + s.version = RCT_VERSION + PKG_REVISION + s.summary = "rcodetools is a collection of Ruby code manipulation tools" + s.description = <, "Mauricio Fernandez" } + s.homepage = "http://eigenclass.org/hiki.rb?rcodetools" + s.bindir = "bin" + s.executables = %w[rct-complete rct-doc xmpfilter rct-meth-args] + s.has_rdoc = true + s.extra_rdoc_files = %w[README] + s.rdoc_options << "--main" << "README" << "--title" << 'rcodetools' + s.test_files = Dir["test/test_*.rb"] + s.post_install_message = < [:test] + Rake::GemPackageTask.new(Spec) do |p| + #p.need_tar = true + end + +rescue LoadError + # RubyGems not installed +end + +desc "install by setup.rb" +task :install do + sh "sudo ruby setup.rb install" +end + +# vim: set sw=2 ft=ruby: diff --git a/Support/vendor/rcodetools-old/Rakefile.method_analysis b/Support/vendor/rcodetools-old/Rakefile.method_analysis new file mode 100644 index 0000000..1dc8e04 --- /dev/null +++ b/Support/vendor/rcodetools-old/Rakefile.method_analysis @@ -0,0 +1,30 @@ + +# Rake tasks to generate TAGS and gather method analysis information. +# See README.method_analysis for more information. + +## my standard Rakefile +task :tags => "TAGS" + +desc "Generate method_analysis by ruby -rmethod_analyzer." +task :analyze => [:_prepare_method_analyze, :tags] do + at_exit { sh "ls -l method_analysis" } +end + +task :_prepare_method_analyze do + ENV['METHOD_ANALYZER_FORMAT']="marshal" + sh "rm -f method_analysis" + puts "generating method_analysis" +end + +## application-specific Rakefile (RTtool) +task :analyze do + sh "ruby -Ilib -rmethod_analyzer test/test.rb" + sh "ruby -Ilib -rmethod_analyzer test/test-rt2html-lib.rb" + sh "ruby -Ilib -rmethod_analyzer test/test-rtparser.rb" +end + +file "TAGS" => FileList["lib/rt/*.rb"] do + sh "rct-meth-args -t lib/rt/*.rb > TAGS" +end + + diff --git a/Support/vendor/rcodetools-old/THANKS b/Support/vendor/rcodetools-old/THANKS new file mode 100644 index 0000000..0ed1e37 --- /dev/null +++ b/Support/vendor/rcodetools-old/THANKS @@ -0,0 +1,11 @@ +Some names forgotten, tell me if you care :) -- mfp + +rubikitch +* expanded xmp3.rb (a previous version of xmpfilter.rb) to support RSpec expectations +* wrote the elisp magic to use xmpfilter.rb with emacs +* made the 100% accurate, editor-independent completion system +[rubikitch took xmpfilter and turned it into the much more powerful +rcodetools, so there are way too many things to list them here :)] + +Adagios +* found & fixed problem with rcodetools.vim plugin on win32 diff --git a/Support/vendor/rcodetools-old/bin/rct-complete b/Support/vendor/rcodetools-old/bin/rct-complete new file mode 100755 index 0000000..2a4398a --- /dev/null +++ b/Support/vendor/rcodetools-old/bin/rct-complete @@ -0,0 +1,40 @@ +#!/usr/bin/env ruby +require 'rcodetools/xmpfilter' +require 'rcodetools/completion' +require 'rcodetools/options' + +options = DEFAULT_OPTIONS +klass = XMPCompletionFilter + +opts = OptionParser.new do |opts| + opts.extend OptionHandler + opts.set_banner + + opts.separator "" + opts.separator "Modes:" + opts.on("-C", "--completion", "List completion candidates.(default)") do + klass = XMPCompletionFilter + end + opts.on("--completion-emacs", "Generate completion code for Emacs.") do + klass = XMPCompletionEmacsFilter + end + opts.on("--completion-emacs-icicles", "Generate completion code for Emacs/Icicles.") do + klass = XMPCompletionEmacsIciclesFilter + end + opts.on("--completion-class-info", "List completion candidates with class.") do + klass = XMPCompletionClassInfoFilter + end + + opts.handle_position options + opts.handle_interpreter options + opts.handle_misc options +end + +set_extra_opts options +opts.parse!(ARGV) + +targetcode = ARGF.read +Dir.chdir options[:wd] if options[:wd] + +# Do the job. dispatched by klass. +puts klass.run(targetcode, options) diff --git a/Support/vendor/rcodetools-old/bin/rct-doc b/Support/vendor/rcodetools-old/bin/rct-doc new file mode 100755 index 0000000..9f3b9b4 --- /dev/null +++ b/Support/vendor/rcodetools-old/bin/rct-doc @@ -0,0 +1,50 @@ +#!/usr/bin/env ruby +require 'rcodetools/xmpfilter' +require 'rcodetools/doc' +require 'rcodetools/options' + +options = DEFAULT_OPTIONS +klass = XMPDocFilter + +opts = OptionParser.new do |opts| + opts.extend OptionHandler + opts.set_banner + + opts.separator "" + opts.separator "Modes:" + opts.on("-D", "--doc", "Print callee method with class.(default)") do + klass = XMPDocFilter + end + opts.on("--refe", "Refe callee method.") do + klass = XMPReFeFilter + end + opts.on("--ri", "Ri callee method.") do + klass = XMPRiFilter + end + opts.on("--ri-emacs", "Generate ri code for emacs.") do + klass = XMPRiEmacsFilter + end + opts.on("--ri-vim", "Generate ri code for vim.") do + klass = XMPRiVimFilter + end + opts.separator "" + opts.on("--use-method-analyzer", "") do |n| + options[:use_method_analyzer] = true + end + opts.on("--filename=FILENAME") do |n| + options[:filename] = File.expand_path n + end + + opts.handle_position options + opts.handle_interpreter options + opts.handle_misc options +end + +set_extra_opts options +opts.parse!(ARGV) + +targetcode = ARGF.read +Dir.chdir options[:wd] if options[:wd] + +# Do the job. dispatched by klass. +puts klass.run(targetcode, options) diff --git a/Support/vendor/rcodetools-old/bin/rct-meth-args b/Support/vendor/rcodetools-old/bin/rct-meth-args new file mode 100755 index 0000000..3488e5d --- /dev/null +++ b/Support/vendor/rcodetools-old/bin/rct-meth-args @@ -0,0 +1,411 @@ +#!/usr/bin/env ruby +# Copyright (c) +# 2006-2007 Mauricio Fernandez http://eigenclass.org +# 2006-2007 rubikitch http://www.rubyist.net/~rubikitch/ +# +# Use and distribution subject to the same conditions as Ruby. + +require 'rcodetools/options' +$VERBOSE = nil +$__method_args_off = true + +if ARGV.empty? or ARGV.include? '-h' or ARGV.include? '--help' + puts < [ ...] + +-Idirectory specify $LOAD_PATH directory (same as ruby) +--dev Add this project's bin/ and lib/ to $LOAD_PATH. + A directory that has Rakefile is considered as project base direcotry. +-i omit instance methods defined in classes +-m omit instance methods defined in modules +-c omit class methods + +-n print the filename and line number with output lines +-t generate TAGS output + +The given files will be #require()d in order. +Examples: + rct-meth-args complex + rct-meth-args thread + rct-meth-args -c rubygems +EOF + exit +end + +def debugprint(*args) + $stderr.puts(*args) if $DEBUG +end + +module MethodArgs + MAX_ARGS = 20 + + private + def needed_args(arity) + arity >= 0 ? arity : arity.abs - 1 + end + + def with_tracer + begin + set_trace_func @__trace_func + yield + ensure + set_trace_func nil + end + end + + module LineContents + # usage: Contents[filename][lineno] + Contents = Hash.new{ |h,k| + sum = 0 + # Unshift is needed because lineno starts with 1. + h[k] = File.readlines(k).map{ |line| [line.chomp, sum+=line.length] }.unshift nil + } + def content + Contents[filename][lineno.to_i][0] rescue "" + end + + def byte + Contents[filename][lineno.to_i-1][1] rescue 0 + end + + def arg_desc + # TODO + desc = content[ /\((.+)\)/] + desc.gsub!(/(\S),(\S)/, '\1, \2') + desc.gsub!(/(\S)=(\S)/, '\1 = \2') + desc + end + + FileNameCache = Hash.new{ |h,k| h[k] = File.expand_path(k) } + def full_filename + FileNameCache[filename] + end + end + + class Location < Struct.new(:filename, :lineno) + include LineContents + end + + class Printer + def method_info(io, x) + prefix = x[:location] ? "#{x[:location].filename}:#{x[:location].lineno}:" : "" + io.puts "#{prefix}#{x[:fullname]}#{x[:arg_desc]}" unless x[:klass].to_s == "" + end + + def included_location(io, x) + x[:callsite] and io.print "#{x[:callsite].filename}:#{x[:callsite].lineno}:" + io.puts([ x[:comment], x[:mod], x[:flag], x[:self] ].join(" ")) + end + end + + class TagsPrinter + def initialize + @previous_filename = "" + end + + def output_filename(filename) + if @previous_filename != filename + @previous_filename = filename + puts "\cl" + puts "#{filename},0" + end + end + + def method_info(io, x) + return unless x[:location] + output_filename x[:location].full_filename + io.puts "#{x[:location].content}::#{x[:fullname]}#{x[:location].lineno},#{x[:location].byte}" + end + + def included_location(io, x) + return unless x[:callsite] + output_filename x[:callsite].full_filename + io.puts "#{x[:callsite].content}::#{x[:mod]}#{x[:callsite].lineno},#{x[:callsite].byte}" + end + end + + def _print_method_info(klass, is_singleton, meth, arg_desc=nil, location=nil, with_location=$__with_location, printer=$__printer) + arg_desc ||= "(...)" + arg_desc = " " + arg_desc unless arg_desc.empty? + flag = is_singleton ? "." : "#" + x = { :arg_desc => arg_desc, :klass => klass, + :fullname => [klass, flag, meth].join, + :location => with_location && location, + } + printer.method_info $>, x + end + + def output_attr_info(klass, object, meth, is_singleton, location) + arg_desc = meth.to_s =~ /=$/ ? "(value)" : "" + _print_method_info klass, is_singleton, meth, arg_desc, location + end + + def output_method_info(klass, object, meth, is_singleton = false, by_attr = nil, by_define_method = nil) + return if $__method_args_off + file = line = params = values = nil + location = nil + begin + unless %w[initialize].include?(meth.to_s) + if is_singleton + return if class << klass; private_instance_methods(true) end.include?(meth.to_s) + else + return if class << object; private_instance_methods(true) end.include?(meth.to_s) + end + end + rescue TypeError # no virtual class + end + + arity = is_singleton ? object.method(meth).arity : klass.instance_method(meth).arity + @__trace_func = lambda{|event, file, line, id, binding, classname| + begin + debugprint "!EVENT: #{event} #{classname}##{id}, #{file} #{line}" + debugprint "(#{self} #{meth})" + if event[/call/] && classname == self && id == meth + location = Location.new(file, line) if event == 'call' + debugprint "EVENT: #{event} #{classname}##{id}" + throw :done + end + rescue Exception + nil # rcov workaround + end + } + if by_define_method + _print_method_info klass, is_singleton, meth, nil, by_define_method + return + end + + if by_attr + output_attr_info klass, object, meth, is_singleton, by_attr + return + end + + catch(:done) do + begin + with_tracer { object.send(meth, *(0...needed_args(arity))) } + rescue Exception + nil # rcov workaround + end + end + + arg_desc = location.arg_desc + + _print_method_info klass, is_singleton, meth, arg_desc, location + rescue Exception + debugprint "GOT EXCEPTION while processing #{klass} #{meth}" + debugprint $!.class + debugprint $!.message + debugprint $!.backtrace + _print_method_info klass, is_singleton, meth, nil, location + ensure + set_trace_func(nil) + end +end + +class Object + include MethodArgs +end + +class Module + class CallSite # compatible with Location + include MethodArgs::LineContents + def initialize(caller_string) + @filename, @lineno, @in = caller_string.split(/:/) + end + attr_reader :filename, :lineno + end + + def _method_defined_with(ivar, caller, &block) + begin + instance_variable_set(ivar, caller) + yield + ensure + instance_variable_set(ivar, false) + end + end + + def with_attr(caller, &block) + _method_defined_with :@by_attr, caller, &block + end + + def with_define_method(caller, &block) + _method_defined_with :@by_define_method, caller, &block + end + + [ :attr, :attr_reader, :attr_writer, :attr_accessor ].each do |meth| + attr = instance_method(meth) + define_method(meth) do |*args| + with_attr(CallSite.new(caller(1)[0])){ attr.bind(self).call(*args) } + end + end + + alias :__define_method_orig :define_method + def define_method(*args, &body) + with_define_method(CallSite.new(caller(1)[0])){ __define_method_orig(*args, &body) } + end + +end + +new_args = [] +omissions = {} +$__with_location = false +$__printer = Printer.new +i_opt_p = false + +ARGV.each do |arg| + case arg + when "-n"; $__with_location = true + when "-t"; $__printer = TagsPrinter.new; $__with_location = true + when /-I(.+)$/; $:.unshift $1 + when "-I"; i_opt_p = true + when "--dev"; OptionHandler.auto_include_paths($:, Dir.pwd) + when /^-.$/; omissions[$&] = true + else + if i_opt_p + $:.unshift arg + i_opt_p = false + else + new_args << arg + end + end +end + +ARGV.replace new_args + +class Object + ALLOCATOR = Hash.new{|h,k| h[k] = k.allocate }.merge(Fixnum=>1, + Bignum=>10000000000000000, + Float=>1.1, + Symbol=>:method_args_tmp, + Binding=>binding, + UnboundMethod=>instance_method(:object_id), + Method=>method(:object_id), + Proc=>lambda{}, + Continuation=>callcc{|c|c}, + Thread=>Thread.new{}, + FalseClass=>false, + TrueClass=>true, + NilClass=>nil, + Struct=>Struct.new(:a).new(1)) + +# ABSTRACT_CLASSES = %w[Digest::Base ] + def self.method_added(meth) +# if ABSTRACT_CLASSES.include? self.to_s +# _print_method_info self, false, meth +# return +# end + begin + o = ALLOCATOR[self] + rescue Exception # for abstract classes + nil + end + output_method_info(self, o, meth, false, @by_attr, @by_define_method) + end +end unless omissions["-i"] + +class Module + method_added = instance_method(:method_added) + define_method(:method_added) do |meth| + begin + if instance_of? Module + o = Object.new + o.extend(self) + output_method_info(self, o, meth, false, @by_attr, @by_define_method) + end + method_added.bind(self).call(meth) + rescue Exception + _print_method_info self, false, meth + end + end +end unless omissions["-m"] + + +class Class + def singleton_method_added(meth) + by_attr = class << self; @by_attr; end + by_define_method = class << self; @by_define_method; end + output_method_info(self, self, meth, true, by_attr, by_define_method) + rescue Exception + _print_method_info self, true, meth + end +end unless omissions["-c"] + +#### include / extend +class Module + def _print_included_location(mod, caller_string, comment, flag, with_location=$__with_location, printer=$__printer) + if caller_string # nil when the class is defined by C + x = { :comment => comment, :mod => mod, :flag => flag, :self => self, + :callsite => with_location && CallSite.new(caller_string) + } + printer.included_location $>, x + end + end + + undef_method :included + def included(mod) + _print_included_location mod, caller(0)[1], "include", "<=" + end + + undef_method :extended + def extended(mod) + _print_included_location mod, caller(0)[1], "extend", "<-" if Module === mod + end +end + +#### inheritance +class Class + undef :inherited + def inherited(klass, caller_level=0) + _print_included_location klass, caller(caller_level)[1], "class", "<" unless self == Object + end +end + +#### Struct inspection +class << Struct + def to_s + orig = super + if orig =~ /" : "" + else + orig + end + end + + def inherited(klass) + if self == Struct + @inherited_delay = lambda{ super(klass, 3) } + else + super(klass, 1) + end + end + + @@struct_initializing = false + def method_added(meth) + super unless @@struct_initializing + end + + orig_new = instance_method(:new) + define_method(:new) do |*args| + begin + @@struct_initializing = true + orig_new.bind(self).call(*args) + ensure + @@struct_initializing = false + @inherited_delay[] + end + end + +end + +$__method_args_off = false + +ARGV.each{|x| + begin + require x + rescue LoadError + load x + end +} + +$__method_args_off = true +# END { puts "zzzz OK" } diff --git a/Support/vendor/rcodetools-old/bin/xmpfilter b/Support/vendor/rcodetools-old/bin/xmpfilter new file mode 100755 index 0000000..dc05419 --- /dev/null +++ b/Support/vendor/rcodetools-old/bin/xmpfilter @@ -0,0 +1,75 @@ +#!/usr/bin/env ruby +require 'rcodetools/xmpfilter' +require 'rcodetools/options' + +options = DEFAULT_OPTIONS +rails_settings = false +klass = XMPFilter + +opts = OptionParser.new do |opts| + opts.extend OptionHandler + opts.set_banner + + opts.separator "" + opts.separator "Modes:" + opts.on("-a", "--annotations", "Annotate code (default)") do + klass = XMPFilter + end + opts.on("-u", "--unittest", "Complete Test::Unit assertions.") do + require 'rcodetools/xmptestunitfilter' + klass = XMPTestUnitFilter + end + opts.on("-s", "--spec", "Complete RSpec expectations.") do + require 'rcodetools/xmptestunitfilter' + klass = XMPRSpecFilter + options[:interpreter] = "spec" + end + opts.on("-m", "--markers", "Add # => markers.") do + klass = XMPAddMarkers + end + + opts.handle_interpreter options + + opts.separator "" + opts.separator "Specific options:" + opts.on("-l N", "--min-line-length N", Integer, "Align markers to N spaces.") do |min_codeline_size| + options[:min_codeline_size] = min_codeline_size + end + opts.on("--rails", "Setting appropriate for Rails.", + "(no warnings, find working directory,", + " Test::Unit assertions)") do + require 'rcodetools/xmptestunitfilter' + options[:warnings] = false + klass = XMPTestUnitFilter + rails_settings = true + end + opts.on("--[no-]poetry", "Whether to use extra parentheses.", + "(default: use them)") do |poetry_p| + options[:use_parentheses] = !poetry_p + end + opts.on("--[no-]warnings", "Whether to add warnings (# !>).", + "(default: enabled)") {|warnings_p| options[:warnings] = warnings_p } + opts.on("-q", "--quiet", "Supress standard output.") do + options[:output_stdout] = false + end + + opts.handle_misc options +end + +set_extra_opts options +opts.parse!(ARGV) + +if rails_settings && !options[:wd] + if File.exist? ARGF.path + options[:wd] = File.dirname(ARGF.path) + elsif File.exist? "test/unit" + options[:wd] = "test/unit" + elsif File.exist? "unit" + options[:wd] = "unit" + end +end +targetcode = ARGF.read +Dir.chdir options[:wd] if options[:wd] + +# Do the job. dispatched by klass. +puts klass.run(targetcode, options) diff --git a/Support/vendor/rcodetools-old/icicles-rcodetools.el b/Support/vendor/rcodetools-old/icicles-rcodetools.el new file mode 100644 index 0000000..a6de2ca --- /dev/null +++ b/Support/vendor/rcodetools-old/icicles-rcodetools.el @@ -0,0 +1,35 @@ +;;; icicles-rcodetools.el -- accurate completion with icicles + +;;; Copyright (c) 2006-2007 rubikitch +;;; +;;; Use and distribution subject to the terms of the Ruby license. + +(require 'icicles) +(require 'rcodetools) + +(setq rct-complete-symbol-function 'rct-complete-symbol--icicles) +(icicle-define-command rct-complete-symbol--icicles + "Perform ruby method and class completion on the text around point with icicles. +C-M-RET shows RI documentation on each candidate. +See also `rct-interactive'." + + (lambda (result) + (save-excursion + (search-backward pattern) + (setq beg (point))) + (delete-region beg end) + (insert result)) ;/function + "rct-complete: " ;prompt + rct-method-completion-table + nil nil pattern nil nil nil + ((end (point)) beg + (icicle-list-join-string "\t") + (icicle-list-use-nth-parts '(1)) + (icicle-point-position-in-candidate 'input-end) + pattern klass alist + (icicle-candidate-help-fn + (lambda (result) + (ri (cdr (assoc result alist)))))) ;bindings + (rct-exec-and-eval rct-complete-command-name "--completion-emacs-icicles")) + +(provide 'icicles-rcodetools) diff --git a/Support/vendor/rcodetools-old/lib/method_analyzer.rb b/Support/vendor/rcodetools-old/lib/method_analyzer.rb new file mode 100644 index 0000000..4f71cc2 --- /dev/null +++ b/Support/vendor/rcodetools-old/lib/method_analyzer.rb @@ -0,0 +1,107 @@ +class Module + remove_method :attr_reader + def attr_reader(*names) + names.each do |name| + module_eval "def #{name}() @#{name} end" + end + end + remove_method :attr_writer + def attr_writer(*names) + names.each do |name| + module_eval "def #{name}=(x) @#{name}=x end" + end + end + remove_method :attr_accessor + def attr_accessor(*names) + attr_reader(*names) + attr_writer(*names) + end + remove_method :attr + def attr(name, writer=false) + attr_reader name + attr_writer name if writer + end +end + + +module MethodAnalyzer + @@methods = Hash.new{ |h,k| h[k] = Hash.new{ |h,k| h[k] = []} } + @@whereis = [] + @@expand_path = Hash.new{ |h,k| h[k] = File.expand_path(k)} + + def self.trace_func(event, file, line, id, binding, klass, *rest) + return if file == __FILE__ + return if (event != 'call' and event != 'c-call') + return if klass == Class and id == :inherited + return if klass == Module and id == :method_added + return if klass == Kernel and id == :singleton_method_added + saved_crit = Thread.critical + Thread.critical = true + + the_self = eval("self",binding) + flag = Class === the_self ? "." : "#" + #klass = klass == Kernel ? Object : klass + fullname = "#{klass}#{flag}#{id}" + file.replace @@expand_path[file] + if event == 'call' + @@whereis << [file, line, fullname] if file !~ /\(eval\)$/ + file, line, rest = caller(4)[0].split(/:/) + file.replace @@expand_path[file] # DRY + p caller(0) if $DEBUG + line = line.to_i + end + @@methods[file][line] << fullname if event =~ /call/ + + Thread.critical = saved_crit + end + + def self.at_exit__output_marshal + at_exit do + set_trace_func nil + dbfile = "method_analysis" + old = Marshal.load(File.read(dbfile)) rescue {} + open(dbfile, "wb") do |io| + # Because Marshal.dump cannot handle hashes with default_proc + @@methods.default = nil + @@methods.each_value{ |v| v.default=nil; v.each_value{ |vv| vv.uniq! } } + Marshal.dump(@@methods.merge(old), io) + end + end + end + + + def self.at_exit__output_text + at_exit do + set_trace_func nil + puts "method fullnames" + @@methods.sort.each do |file, lines| + lines.sort.each do |line, methods| + printf "%s:%s:%s\n", file, line, methods.uniq.join(" ") + end + end + + puts + puts "method definitions" + @@whereis.sort.uniq.each do |file, line, fullname | + printf "%s:%s:%s\n", file, line, fullname + end + + end + end + + def self.set_at_exit + case ENV['METHOD_ANALYZER_FORMAT'] + when 'marshal' + at_exit__output_marshal + else + at_exit__output_text + end + end + + set_at_exit + set_trace_func method(:trace_func).to_proc +end + +if __FILE__ == $0 + load "./test/data/method_analyzer-data.rb" +end diff --git a/Support/vendor/rcodetools-old/lib/rcodetools/completion.rb b/Support/vendor/rcodetools-old/lib/rcodetools/completion.rb new file mode 100644 index 0000000..4ea1320 --- /dev/null +++ b/Support/vendor/rcodetools-old/lib/rcodetools/completion.rb @@ -0,0 +1,361 @@ +# Nearly 100% accurate completion for any editors!! +# by rubikitch + +require 'rcodetools/xmpfilter' +require 'enumerator' +# Common routines for XMPCompletionFilter/XMPDocFilter +module ProcessParticularLine + def fill_literal!(expr) + [ "\"", "'", "`" ].each do |q| + expr.gsub!(/#{q}(.+)#{q}/){ '"' + "x"*$1.length + '"' } + end + expr.gsub!(/(%([wWqQxrs])?(\W))(.+?)\3/){ + percent = $2 == 'x' ? '%'+$3 : $1 # avoid executing shell command + percent + "x"*$4.length + $3 + } + [ %w[( )], %w[{ }], %w![ ]!, %w[< >] ].each do |b,e| + rb, re = [b,e].map{ |x| Regexp.quote(x)} + expr.gsub!(/(%([wWqQxrs])?(#{rb}))(.+)#{re}/){ + percent = $2 == 'x' ? '%'+$3 : $1 # avoid executing shell command + percent + "x"*$4.length + e + } + end + end + + module ExpressionExtension + attr_accessor :eval_string + attr_accessor :meth + end + OPERATOR_CHARS = '\|^&<>=~\+\-\*\/%\[' + def set_expr_and_postfix!(expr, column, ®exp) + expr.extend ExpressionExtension + + @postfix = "" + expr_orig = expr.clone + column ||= expr.length + last_char = expr[column-1] + expr.replace expr[ regexp[column] ] + debugprint "expr_orig=#{expr_orig}", "expr(sliced)=#{expr}" + right_stripped = Regexp.last_match.post_match + _handle_do_end right_stripped + aref_or_aset = aref_or_aset? right_stripped, last_char + debugprint "aref_or_aset=#{aref_or_aset.inspect}" + set_last_word! expr, aref_or_aset + fill_literal! expr_orig + _handle_brackets expr_orig, expr + expr << aref_or_aset if aref_or_aset + _handle_keywords expr_orig, column + debugprint "expr(processed)=#{expr}" + expr + end + + def _handle_do_end(right_stripped) + right_stripped << "\n" + n_do = right_stripped.scan(/[\s\)]do\s/).length + n_end = right_stripped.scan(/\bend\b/).length + @postfix = ";begin" * (n_do - n_end) + end + + def _handle_brackets(expr_orig, expr) + [ %w[{ }], %w[( )], %w![ ]! ].each do |left, right| + n_left = expr_orig.count(left) - expr.count(left) + n_right = expr_orig.count(right) - expr.count(right) + n = n_left - n_right + @postfix << ";#{left}" * n if n >= 0 + end + end + + def _handle_keywords(expr_orig, column) + %w[if unless while until for].each do |keyw| + pos = expr_orig.index(/\b#{keyw}\b/) + @postfix << ";begin" if pos and pos < column # if * xxx + + pos = expr_orig.index(/;\s*#{keyw}\b/) + @postfix << ";begin" if pos and column < pos # * ; if xxx + end + end + + def aref_or_aset?(right_stripped, last_char) + if last_char == ?[ + case right_stripped + when /\]\s*=/: "[]=" + when /\]/: "[]" + end + end + end + + def set_last_word!(expr, aref_or_aset=nil) + debugprint "expr(before set_last_word)=#{expr}" + if aref_or_aset + opchars = "" + else + opchars = expr.slice!(/\s*[#{OPERATOR_CHARS}]+$/) + debugprint "expr(strip opchars)=#{expr}" + end + + expr.replace(if expr =~ /[\"\'\`]$/ # String operations + "''" + else + fill_literal! expr + phrase = current_phrase(expr) + if aref_or_aset + expr.eval_string = expr[0..-2] + expr.meth = aref_or_aset + elsif phrase.match( /^(.+)\.(.*)$/ ) + expr.eval_string, expr.meth = $1, $2 + elsif opchars != '' + expr + end + debugprint "expr.eval_string=#{expr.eval_string}", "expr.meth=#{expr.meth}" + phrase + end << (opchars || '')) # ` font-lock hack + debugprint "expr(after set_last_word)=#{expr}" + end + + def current_phrase(expr) + paren_level = 0 + start = 0 + (expr.length-1).downto(0) do |i| + c = expr[i,1] + if c =~ /[\)\}\]]/ + paren_level += 1 + next + end + if paren_level > 0 + next if c =~ /[, ]/ + else + break (start = i+1) if c =~ /[ ,\(\{\[]/ + end + if c =~ /[\(\{\[]/ + paren_level -= 1 + break (start = i+1) if paren_level < 0 + end + end + expr[start..-1] + end + + def add_BEGIN + <\\Z] )[1].sub(/\\A.*?\\((.*?)\\)(.*)\\Z/){ "\#{$1}\#{$2}" }.sub(/##/) { "\#{$1}." } + #{result} = #{v}.to_s + ".new" if #{result} == 'Class#new' and #{v}.private_method_defined?(:initialize) + #{result} = "Object#" + #{meth} if #{result} =~ /^Kernel#/ and Kernel.instance_methods(false).include? #{meth} + #{result} +EOC + end + +end + +# Nearly 100% accurate completion for any editors!! +# by rubikitch +class XMPCompletionFilter < XMPFilter + include ProcessParticularLine + + class << self + attr_accessor :candidates_with_description_flag + end + @candidates_with_description_flag = false + + # String completion begins with this. + attr :prefix + + def self.run(code, opts) + new(opts).completion_code(code, opts[:lineno], opts[:column]) + end + + def magic_help_code(recv, meth) + oneline_ize __magic_help_code("#{VAR}_result", recv, meth) + end + + def methods_map_code(recv) + # delimiter is \0 + %Q[map{|m| "\#{m}\\0" + #{magic_help_code((recv), 'm')}}] + end + + def split_method_info(minfo) + minfo.split(/\0/,2) + end + + def prepare_line(expr, column) + set_expr_and_postfix!(expr, column){|c| /^.{#{c}}/ } + @prefix = expr + case expr + when /^\$\w+$/ # global variable + __prepare_line 'nil', 'global_variables', '%n' + when /^@@\w+$/ # class variable + __prepare_line 'nil', 'Module === self ? class_variables : self.class.class_variables', '%n' + when /^@\w+$/ # instance variable + __prepare_line 'nil', 'instance_variables', '%n' + when /^([A-Z].*)::([^.]*)$/ # nested constants / class methods + @prefix = $2 + __prepare_line $1, "#$1.constants | #$1.methods(true)", + %Q[#$1.constants + #$1.methods(true).#{methods_map_code($1)}] + when /^[A-Z]\w*$/ # normal constants + __prepare_line 'nil', 'Module.constants', '%n' + when /^(.*::.+)\.(.+)$/ # toplevel class methods + @prefix = $2 + __prepare_line $1, "#$1.methods", + %Q[%n.#{methods_map_code($1)}] + when /^(::.+)::(.*)$/ # toplevel nested constants + @prefix = $2 + __prepare_line $1, "#$1.constants | #$1.methods", + %Q[#$1.constants + #$1.methods.#{methods_map_code($1)}] + when /^::(.*)/ # toplevel constant + @prefix = $1 + __prepare_line 'nil', 'Object.constants', '%n' + when /^(:[^:.]*)$/ # symbol + __prepare_line 'nil', 'Symbol.all_symbols.map{|s| ":" + s.id2name}', '%n' + when /\.([^.]*)$/ # method call + @prefix = $1 + recv = Regexp.last_match.pre_match + __prepare_line recv, "(#{recv}).methods(true)", + %Q[%n.#{methods_map_code(recv)}] + else # bare words + __prepare_line 'self', "methods | private_methods | local_variables | self.class.constants", + %Q[(methods | private_methods).#{methods_map_code('self')} + local_variables | self.class.constants] + end + end + + def __prepare_line(recv, all_completion_expr, all_completion_expr_verbose) + if self.class.candidates_with_description_flag + ___prepare_line(recv, all_completion_expr_verbose.gsub(/%n/, '('+all_completion_expr+')')) + else + ___prepare_line(recv, all_completion_expr) + end + + end + + def ___prepare_line(recv, all_completion_expr) + v = "#{VAR}" + rcv = "#{VAR}_recv" + idx = 1 + oneline_ize(< " + #{rcv}.to_s + " " + #{v}.join(" ")) || #{v} +exit +EOC + end + + # Array of completion candidates. + def candidates(code, lineno, column=nil) + methods = runtime_data(code, lineno, column) rescue "" + methods.split(/ /).sort + end + + # Completion code for editors. + def completion_code(code, lineno, column=nil) + candidates(code, lineno, column).join("\n") + end +end + +# for debugging XMPCompletionEmacsFilter +class XMPCompletionVerboseFilter < XMPCompletionFilter + @candidates_with_description_flag = true +end + +class XMPCompletionClassInfoFilter < XMPCompletionFilter + @candidates_with_description_flag = true + + def completion_code(code, lineno, column=nil) + candidates(code, lineno, column).join("\n").tr("\0", "\t") + end +end + +class XMPCompletionEmacsFilter < XMPCompletionFilter + @candidates_with_description_flag = true + + def completion_code(code, lineno, column=nil) + elisp = "(progn\n" + table = "(setq rct-method-completion-table '(" + alist = "(setq alist '(" + begin + candidates(code, lineno, column).sort.each do |minfo| + meth, description = split_method_info(minfo) + table << format('("%s") ', meth) + alist << format('("%s\\t[%s]") ', meth, description) + end + table << "))\n" + alist << "))\n" + rescue Exception => err + return %Q[(error "#{err.message}")] + end + elisp << table << alist + elisp << %Q[(setq pattern "#{prefix}")\n] + elisp << %Q[(try-completion pattern rct-method-completion-table nil)\n] + elisp << ")" # /progn + end +end + +class XMPCompletionEmacsIciclesFilter < XMPCompletionFilter + @candidates_with_description_flag = true + + def candidates(code, lineno, column=nil) + klass, methods = runtime_data_with_class(code, lineno, column) rescue ["", ""] + @klass = klass + methods.split(/ /).sort + end + + def completion_code(code, lineno, column=nil) + elisp = "(progn\n" + table = "(setq rct-method-completion-table '(" + help_alist = "(setq alist '(" + + begin + candidates(code, lineno, column).sort.each do |minfo| + meth, description = split_method_info(minfo) + table << format('("%s\\t[%s]") ', meth, description) + help_alist << format('("%s" . "%s")', meth, description) + end + table << "))\n" + help_alist << "))\n" + rescue Exception => err + return %Q[(error "#{err.message}")] + end + elisp << table << help_alist + elisp << %Q[(setq pattern "#{prefix}")\n] + elisp << %Q[(setq klass "#{@klass}")\n] + elisp << ")" # /progn + end +end + diff --git a/Support/vendor/rcodetools-old/lib/rcodetools/doc.rb b/Support/vendor/rcodetools-old/lib/rcodetools/doc.rb new file mode 100644 index 0000000..30c3274 --- /dev/null +++ b/Support/vendor/rcodetools-old/lib/rcodetools/doc.rb @@ -0,0 +1,165 @@ +require 'rcodetools/completion' +# Call Ri for any editors!! +# by rubikitch +class XMPDocFilter < XMPFilter + include ProcessParticularLine + + def initialize(opts = {}) + super + @filename = opts[:filename] + extend UseMethodAnalyzer if opts[:use_method_analyzer] + end + + def self.run(code, opts) + new(opts).doc(code, opts[:lineno], opts[:column]) + end + + def prepare_line(expr, column) + set_expr_and_postfix!(expr, column){|c| + withop_re = /^.{#{c-1}}[#{OPERATOR_CHARS}]+/ + if expr =~ withop_re + withop_re + else + /^.{#{c}}[\w#{OPERATOR_CHARS}]*/ + end + } + recv = expr + + # When expr already knows receiver and method, + return(__prepare_line :recv => expr.eval_string, :meth => expr.meth) if expr.eval_string + + case expr + when /^(?:::)?([A-Z].*)(?:::|\.)(.*)$/ # nested constants / class methods + __prepare_line :klass => $1, :meth_or_constant => $2 + when /^(?:::)?[A-Z]/ # normal constants + __prepare_line :klass => expr + when /\.([^.]*)$/ # method call + __prepare_line :recv => Regexp.last_match.pre_match, :meth => $1 + when /^(.+)(\[\]=?)$/ # [], []= + __prepare_line :recv => $1, :meth => $2 + when /[#{OPERATOR_CHARS}]+$/ # operator + __prepare_line :recv => Regexp.last_match.pre_match, :meth => $& + else # bare words + __prepare_line :recv => "self", :meth => expr + end + end + + def __prepare_line(x) + v = "#{VAR}" + result = "#{VAR}_result" + klass = "#{VAR}_klass" + flag = "#{VAR}_flag" + which_methods = "#{VAR}_methods" + ancestor_class = "#{VAR}_ancestor_class" + idx = 1 + recv = x[:recv] || x[:klass] || raise(ArgumentError, "need :recv or :klass") + meth = x[:meth_or_constant] || x[:meth] + debugprint "recv=#{recv}", "meth=#{meth}" + if meth + # imported from fastri/MagicHelp + code = <<-EOC +#{v} = (#{recv}) +$stderr.print("#{MARKER}[#{idx}] => " + #{v}.class.to_s + " ") + +if Module === #{v} and '#{meth}' =~ /^[A-Z]/ and #{v}.const_defined?('#{meth}') + #{result} = #{v}.to_s + "::#{meth}" +else + #{__magic_help_code result, v, meth.dump} +end + +$stderr.puts(#{result}) +exit + EOC + else + code = <<-EOC +#{v} = (#{recv}) +$stderr.print("#{MARKER}[#{idx}] => " + #{v}.class.to_s + " ") +$stderr.puts(#{v}.to_s) +exit + EOC + end + oneline_ize(code) + end + + # overridable by module + def _doc(code, lineno, column) + end + + def doc(code, lineno, column=nil) + _doc(code, lineno, column) or runtime_data(code, lineno, column).to_s + end + + module UseMethodAnalyzer + METHOD_ANALYSIS = "method_analysis" + def have_method_analysis + File.file? METHOD_ANALYSIS + end + + def find_method_analysis + here = Dir.pwd + oldpwd = here + begin + while ! have_method_analysis + Dir.chdir("..") + if Dir.pwd == here + return nil # not found + end + here = Dir.pwd + end + ensure + Dir.chdir oldpwd + end + yield(File.join(here, METHOD_ANALYSIS)) + end + + def _doc(code, lineno, column=nil) + find_method_analysis do |ma_file| + methods = open(ma_file, "rb"){ |f| Marshal.load(f)} + line = File.readlines(@filename)[lineno-1] + current_method = line[ /^.{#{column}}\w*/][ /\w+[\?!]?$/ ].sub(/:+/,'') + filename = @filename # FIXME + begin + methods[filename][lineno].grep(Regexp.new(Regexp.quote(current_method)))[0] + rescue NoMethodError + raise "doc/method_analyzer:cannot find #{current_method}" + end + + end + end + end + +end + +# ReFe is so-called `Japanese Ri'. +class XMPReFeFilter < XMPDocFilter + def doc(code, lineno, column=nil) + "refe '#{super}'" + end +end + +class XMPRiFilter < XMPDocFilter + def doc(code, lineno, column=nil) + "ri '#{super.sub(/\./, '::')}'" + end +end + +class XMPRiEmacsFilter < XMPDocFilter + def doc(code, lineno, column=nil) + begin + %!(rct-find-tag-or-ri "#{super}")! + rescue Exception => err + return %Q[(error "#{err.message}")] + end + end +end + +class XMPRiVimFilter < XMPDocFilter + def doc(code, lineno, column=nil) + begin + %{call RCT_find_tag_or_ri("#{super}")} + rescue Exception => err + return %Q[echo #{err.message.inspect}] + end + end +end + diff --git a/Support/vendor/rcodetools-old/lib/rcodetools/options.rb b/Support/vendor/rcodetools-old/lib/rcodetools/options.rb new file mode 100644 index 0000000..ccf19a3 --- /dev/null +++ b/Support/vendor/rcodetools-old/lib/rcodetools/options.rb @@ -0,0 +1,95 @@ +require 'optparse' + +# Domain specific OptionParser extensions +module OptionHandler + def set_banner + self.banner = "Usage: #{$0} [options] [inputfile] [-- cmdline args]" + end + + def handle_position(options) + separator "" + separator "Position options:" + on("--line=LINE", "Current line number.") do |n| + options[:lineno] = n.to_i + end + on("--column=COLUMN", "Current column number.") do |n| + options[:column] = n.to_i + end + end + + def handle_interpreter(options) + separator "" + separator "Interpreter options:" + on("-S FILE", "--interpreter FILE", "Use interpreter FILE.") do |interpreter| + options[:interpreter] = interpreter + end + on("-I PATH", "Add PATH to $LOAD_PATH") do |path| + options[:include_paths] << path + end + on("--dev", "Add this project's bin/ and lib/ to $LOAD_PATH.", + "A directory with a Rakefile is considered a project base directory.") do + auto_include_paths(options[:include_paths], Dir.pwd) + end + on("-r LIB", "Require LIB before execution.") do |lib| + options[:libs] << lib + end + on("-e EXPR", "--eval=EXPR", "--stub=EXPR", "Evaluate EXPR after execution.") do |expr| + options[:evals] << expr + end + + end + + def handle_misc(options) + separator "" + separator "Misc options:" + on("--cd DIR", "Change working directory to DIR.") do |dir| + options[:wd] = dir + end + on("--debug", "Write transformed source code to xmp-tmp.PID.rb.") do + options[:dump] = "xmp-tmp.#{Process.pid}.rb" + end + separator "" + on("-h", "--help", "Show this message") do + puts self + exit + end + on("-v", "--version", "Show version information") do + puts "#{File.basename($0)} #{XMPFilter::VERSION}" + exit + end + end + + def auto_include_paths(include_paths, pwd) + if pwd =~ %r!^(.+)/(lib|bin)! + include_paths.unshift("#$1/lib").unshift("#$1/bin") + elsif File.file? "#{pwd}/Rakefile" or File.file? "#{pwd}/rakefile" + include_paths.unshift("#{pwd}/lib").unshift("#{pwd}/bin") + end + end + module_function :auto_include_paths + +end + +def set_extra_opts(options) + if idx = ARGV.index("--") + options[:options] = ARGV[idx+1..-1] + ARGV.replace ARGV[0...idx] + else + options[:options] = [] + end +end + +DEFAULT_OPTIONS = { + :interpreter => "ruby", + :options => ["hoge"], + :min_codeline_size => 50, + :libs => [], + :evals => [], + :include_paths => [], + :dump => nil, + :wd => nil, + :warnings => true, + :use_parentheses => true, + :column => nil, + :output_stdout => true, + } diff --git a/Support/vendor/rcodetools-old/lib/rcodetools/xmpfilter.rb b/Support/vendor/rcodetools-old/lib/rcodetools/xmpfilter.rb new file mode 100644 index 0000000..2cd0368 --- /dev/null +++ b/Support/vendor/rcodetools-old/lib/rcodetools/xmpfilter.rb @@ -0,0 +1,209 @@ +#!/usr/bin/env ruby +# Copyright (c) 2005-2007 Mauricio Fernandez http://eigenclass.org +# rubikitch +# Use and distribution subject to the terms of the Ruby license. + +class XMPFilter + VERSION = "0.5.0" + + MARKER = "!XMP#{Time.new.to_i}_#{Process.pid}_#{rand(1000000)}!" + XMP_RE = Regexp.new("^" + Regexp.escape(MARKER) + '\[([0-9]+)\] (=>|~>|==>) (.*)') + VAR = "_xmp_#{Time.new.to_i}_#{Process.pid}_#{rand(1000000)}" + WARNING_RE = /.*:([0-9]+): warning: (.*)/ + + RuntimeData = Struct.new(:results, :exceptions, :bindings) + + INITIALIZE_OPTS = {:interpreter => "ruby", :options => [], :libs => [], + :include_paths => [], :warnings => true, + :use_parentheses => true} + + # The processor (overridable) + def self.run(code, opts) + new(opts).annotate(code) + end + + def initialize(opts = {}) + options = INITIALIZE_OPTS.merge opts + @interpreter = options[:interpreter] + @options = options[:options] + @libs = options[:libs] + @evals = options[:evals] || [] + @include_paths = options[:include_paths] + @output_stdout = options[:output_stdout] + @dump = options[:dump] + @warnings = options[:warnings] + @parentheses = options[:use_parentheses] + @ignore_NoMethodError = options[:ignore_NoMethodError] + + @postfix = "" + end + + def add_markers(code, min_codeline_size = 50) + maxlen = code.map{|x| x.size}.max + maxlen = [min_codeline_size, maxlen + 2].max + ret = "" + code.each do |l| + l = l.chomp.gsub(/ # (=>|!>).*/, "").gsub(/\s*$/, "") + ret << (l + " " * (maxlen - l.size) + " # =>\n") + end + ret + end + + def annotate(code) + idx = 0 + newcode = code.gsub(/^(.*) # =>.*/){|l| prepare_line($1, idx += 1) } + if @dump + File.open(@dump, "w"){|f| f.puts newcode} + end + stdout, stderr = execute(newcode) + output = stderr.readlines + runtime_data = extract_data(output) + idx = 0 + annotated = code.gsub(/^(.*) # =>.*/) do |l| + expr = $1 + if /^\s*#/ =~ l + l + else + annotated_line(l, expr, runtime_data, idx += 1) + end + end.gsub(/ # !>.*/, '').gsub(/# (>>|~>)[^\n]*\n/m, ""); + ret = final_decoration(annotated, output) + if @output_stdout and (s = stdout.read) != "" + ret << s.inject(""){|s,line| s + "# >> #{line}".chomp + "\n" } + end + ret + end + + def annotated_line(line, expression, runtime_data, idx) + "#{expression} # => " + (runtime_data.results[idx].map{|x| x[1]} || []).join(", ") + end + + def prepare_line_annotation(expr, idx) + v = "#{VAR}" + blocal = "__#{VAR}" + blocal2 = "___#{VAR}" + # rubikitch: oneline-ized +# < " + #{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})) +# EOF + oneline_ize(<<-EOF).chomp +#{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} + EOF + + end + alias_method :prepare_line, :prepare_line_annotation + + def execute_tmpfile(code) + stdin, stdout, stderr = (1..3).map do |i| + fname = "xmpfilter.tmpfile_#{Process.pid}-#{i}.rb" + f = File.open(fname, "w+") + at_exit { f.close unless f.closed?; File.unlink fname } + f + end + stdin.puts code + stdin.close + exe_line = <<-EOF.map{|l| l.strip}.join(";") + $stdout.reopen('#{stdout.path}', 'w') + $stderr.reopen('#{stderr.path}', 'w') + $0.replace '#{stdin.path}' + ARGV.replace(#{@options.inspect}) + load #{stdin.path.inspect} + #{@evals.join(";")} + EOF + system(*(interpreter_command << "-e" << exe_line)) + [stdout, stderr] + end + + def execute_popen(code) + require 'open3' + stdin, stdout, stderr = Open3::popen3(*interpreter_command) + stdin.puts code + @evals.each{|x| stdin.puts x } unless @evals.empty? + stdin.close + [stdout, stderr] + end + + if /win|mingw/ =~ RUBY_PLATFORM && /darwin/ !~ RUBY_PLATFORM + alias_method :execute, :execute_tmpfile + else + alias_method :execute, :execute_popen + end + + def interpreter_command + r = [@interpreter, "-wKu"] + r << "-d" if $DEBUG + r << "-I#{@include_paths.join(":")}" unless @include_paths.empty? + @libs.each{|x| r << "-r#{x}" } unless @libs.empty? + (r << "-").concat @options unless @options.empty? + r + end + + def extract_data(output) + results = Hash.new{|h,k| h[k] = []} + exceptions = Hash.new{|h,k| h[k] = []} + bindings = Hash.new{|h,k| h[k] = []} + output.grep(XMP_RE).each do |line| + result_id, op, result = XMP_RE.match(line).captures + case op + when "=>" + klass, value = /(\S+)\s+(.*)/.match(result).captures + results[result_id.to_i] << [klass, value] + when "~>" + exceptions[result_id.to_i] << result + when "==>" + bindings[result_id.to_i] << result unless result.index(VAR) + end + end + RuntimeData.new(results, exceptions, bindings) + end + + def final_decoration(code, output) + warnings = {} + output.join.grep(WARNING_RE).map do |x| + md = WARNING_RE.match(x) + warnings[md[1].to_i] = md[2] + end + idx = 0 + ret = code.map do |line| + w = warnings[idx+=1] + if @warnings + w ? (line.chomp + " # !> #{w}") : line + else + line + end + end + output = output.reject{|x| /^-:[0-9]+: warning/.match(x)} + if exception = /^-:[0-9]+:.*/m.match(output.join) + ret << exception[0].map{|line| "# ~> " + line } + end + ret + end + + def oneline_ize(code) + "((" + code.gsub(/\r?\n|\r/, ';') + "))#{@postfix}\n" + end + + def debugprint(*args) + $stderr.puts(*args) if $DEBUG + end +end # clas XMPFilter + +class XMPAddMarkers < XMPFilter + def self.run(code, opts) + new(opts).add_markers(code, opts[:min_codeline_size]) + end +end diff --git a/Support/vendor/rcodetools-old/lib/rcodetools/xmptestunitfilter.rb b/Support/vendor/rcodetools-old/lib/rcodetools/xmptestunitfilter.rb new file mode 100644 index 0000000..e89354b --- /dev/null +++ b/Support/vendor/rcodetools-old/lib/rcodetools/xmptestunitfilter.rb @@ -0,0 +1,197 @@ +require 'rcodetools/xmpfilter' +class XMPTestUnitFilter < XMPFilter + def initialize(opts = {}) + super + @output_stdout = false + mod = @parentheses ? :WithParentheses : :Poetry + extend self.class.const_get(mod) + end + + private + def annotated_line(line, expression, runtime_data, idx) + indent = /^\s*/.match(line)[0] + assertions(expression.strip, runtime_data, idx).map{|x| indent + x}.join("\n") + end + + def prepare_line(expr, idx) + basic_eval = prepare_line_annotation(expr, idx) + %|begin; #{basic_eval}; rescue Exception; $stderr.puts("#{MARKER}[#{idx}] ~> " + $!.class.to_s); end| + end + + def assertions(expression, runtime_data, index) + exceptions = runtime_data.exceptions + ret = [] + + unless (vars = runtime_data.bindings[index]).empty? + vars.each{|var| ret << equal_assertion(var, expression) } + end + if !(wanted = runtime_data.results[index]).empty? || !exceptions[index] + case (wanted[0][1] rescue 1) + when "nil" + ret.concat nil_assertion(expression) + else + case wanted.size + when 1 + ret.concat _value_assertions(wanted[0], expression) + else + # discard values from multiple runs + ret.concat(["#xmpfilter: WARNING!! extra values ignored"] + + _value_assertions(wanted[0], expression)) + end + end + else + ret.concat raise_assertion(expression, exceptions, index) + end + + ret + end + + OTHER = Class.new + def _value_assertions(klass_value_txt_pair, expression) + klass_txt, value_txt = klass_value_txt_pair + value = eval(value_txt) || OTHER.new + # special cases + value = nil if value_txt.strip == "nil" + value = false if value_txt.strip == "false" + value_assertions klass_txt, value_txt, value, expression + rescue Exception + return object_assertions(klass_txt, value_txt, expression) + end + + def raise_assertion(expression, exceptions, index) + ["assert_raise(#{exceptions[index][0]}){#{expression}}"] + end + + module WithParentheses + def nil_assertion(expression) + ["assert_nil(#{expression})"] + end + + def value_assertions(klass_txt, value_txt, value, expression) + case value + when Float + ["assert_in_delta(#{value.inspect}, #{expression}, 0.0001)"] + when Numeric, String, Hash, Array, Regexp, TrueClass, FalseClass, Symbol, NilClass + ["assert_equal(#{value_txt}, #{expression})"] + else + object_assertions(klass_txt, value_txt, expression) + end + end + + def object_assertions(klass_txt, value_txt, expression) + [ "assert_kind_of(#{klass_txt}, #{expression})", + "assert_equal(#{value_txt.inspect}, #{expression}.inspect)" ] + end + + def equal_assertion(expected, actual) + "assert_equal(#{expected}, #{actual})" + end + end + + module Poetry + def nil_assertion(expression) + ["assert_nil #{expression}"] + end + + def value_assertions(klass_txt, value_txt, value, expression) + case value + when Float + ["assert_in_delta #{value.inspect}, #{expression}, 0.0001"] + when Numeric, String, Hash, Array, Regexp, TrueClass, FalseClass, Symbol, NilClass + ["assert_equal #{value_txt}, #{expression}"] + else + object_assertions klass_txt, value_txt, expression + end + end + + def object_assertions(klass_txt, value_txt, expression) + [ "assert_kind_of #{klass_txt}, #{expression} ", + "assert_equal #{value_txt.inspect}, #{expression}.inspect" ] + end + + def equal_assertion(expected, actual) + "assert_equal #{expected}, #{actual}" + end + end +end + +class XMPRSpecFilter < XMPTestUnitFilter + private + def execute(code) + codefile = "xmpfilter.rspec_tmpfile_#{Process.pid}.rb" + File.open(codefile, "w"){|f| f.puts code} + path = File.expand_path(codefile) + at_exit { File.unlink path if File.exist? path} + stdout, stderr = (1..2).map do |i| + fname = "xmpfilter.rspec_tmpfile_#{Process.pid}-#{i}.rb" + fullname = File.expand_path(fname) + at_exit { File.unlink fullname if File.exist? fullname} + File.open(fname, "w+") + end + args = *(interpreter_command << %["#{codefile}"] << "2>" << + %["#{stderr.path}"] << ">" << %["#{stdout.path}"]) + system(args.join(" ")) + [stdout, stderr] + end + + def interpreter_command + [@interpreter] + @libs.map{|x| "-r#{x}"} + end + + def raise_assertion(expression, exceptions, index) + ["lambda{#{expression}}.should_raise #{exceptions[index][0]}"] + end + + module WithParentheses + def nil_assertion(expression) + ["(#{expression}).should_be_nil"] + end + + def value_assertions(klass_txt, value_txt, value, expression) + case value + when Float + ["(#{expression}).should_be_close #{value.inspect}, 0.0001"] + when Numeric, String, Hash, Array, Regexp, TrueClass, FalseClass, Symbol, NilClass + ["(#{expression}).should_equal #{value_txt}"] + else + object_assertions klass_txt, value_txt, expression + end + end + + def object_assertions(klass_txt, value_txt, expression) + [ "(#{expression}).should_be_a_kind_of #{klass_txt}", + "(#{expression}.inspect).should_equal #{value_txt.inspect}" ] + end + + def equal_assertion(expected, actual) + "(#{actual}).should_equal #{expected}" + end + end + + module Poetry + def nil_assertion(expression) + ["#{expression}.should_be_nil"] + end + + def value_assertions(klass_txt, value_txt, value, expression) + case value + when Float + ["#{expression}.should_be_close #{value.inspect}, 0.0001"] + when Numeric, String, Hash, Array, Regexp, TrueClass, FalseClass, Symbol, NilClass + ["#{expression}.should_equal #{value_txt}"] + else + object_assertions klass_txt, value_txt, expression + end + end + + def object_assertions(klass_txt, value_txt, expression) + [ "#{expression}.should_be_a_kind_of #{klass_txt}", + "#{expression}.inspect.should_equal #{value_txt.inspect}" ] + end + + def equal_assertion(expected, actual) + "#{actual}.should_equal #{expected}" + end + end +end + diff --git a/Support/vendor/rcodetools-old/rcodetools.el b/Support/vendor/rcodetools-old/rcodetools.el new file mode 100644 index 0000000..4c2e441 --- /dev/null +++ b/Support/vendor/rcodetools-old/rcodetools.el @@ -0,0 +1,217 @@ +;;; rcodetools.el -- annotation / accurate completion / browsing documentation + +;;; Copyright (c) 2006 rubikitch +;;; +;;; Use and distribution subject to the terms of the Ruby license. + +(defvar xmpfilter-command-name "ruby -S xmpfilter --dev --detect-rbtest" + "The xmpfilter command name.") +(defvar rct-doc-command-name "ruby -S rct-doc --dev --fork --detect-rbtest" + "The rct-doc command name.") +(defvar rct-complete-command-name "ruby -S rct-complete --dev --fork --detect-rbtest" + "The rct-complete command name.") +(defvar ruby-toggle-file-command-name "ruby -S ruby-toggle-file" + "The ruby-toggle-file command name.") +(defvar rct-option-history nil) ;internal +(defvar rct-option-local nil) ;internal +(make-variable-buffer-local 'rct-option-local) +(defvar rct-debug nil + "If non-nil, output debug message into *Messages*.") +;; (setq rct-debug t) + +(defadvice comment-dwim (around rct-hack activate) + "If comment-dwim is successively called, add => mark." + (if (and (eq major-mode 'ruby-mode) + (eq last-command 'comment-dwim) + ;; TODO =>check + ) + (insert "=>") + ad-do-it)) +;; To remove this advice. +;; (progn (ad-disable-advice 'comment-dwim 'around 'rct-hack) (ad-update 'comment-dwim)) + +(defun rct-current-line () + "Return the vertical position of point..." + (+ (count-lines (point-min) (point)) + (if (= (current-column) 0) 1 0))) + +(defun rct-save-position (proc) + "Evaluate proc with saving current-line/current-column/window-start." + (let ((line (rct-current-line)) + (col (current-column)) + (wstart (window-start))) + (funcall proc) + (goto-char (point-min)) + (forward-line (1- line)) + (move-to-column col) + (set-window-start (selected-window) wstart))) + +(defun rct-interactive () + "All the rcodetools-related commands with prefix args read rcodetools' common option. And store option into buffer-local variable." + (list + (let ((option (or rct-option-local ""))) + (if current-prefix-arg + (setq rct-option-local + (read-from-minibuffer "rcodetools option: " option nil nil 'rct-option-history)) + option)))) + +(defun xmp (&optional option) + "Run xmpfilter for annotation/test/spec on whole buffer. +See also `rct-interactive'. " + (interactive (rct-interactive)) + (rct-save-position + (lambda () (shell-command-on-region (point-min) (point-max) (xmpfilter-command option) t t " *rct-error*")))) + +(defun xmpfilter-command (&optional option) + "The xmpfilter command line, DWIM." + (setq option (or option "")) + (cond ((save-excursion + (goto-char 1) + (search-forward "< Test::Unit::TestCase" nil t)) + (format "%s --unittest %s" xmpfilter-command-name option)) + ((save-excursion + (goto-char 1) + (re-search-forward "^context.+do$" nil t)) + (format "%s --spec %s" xmpfilter-command-name option)) + (t + (format "%s %s" xmpfilter-command-name option)))) + +;;;; Completion +(defvar rct-method-completion-table nil) ;internal +(defvar rct-complete-symbol-function 'rct-complete-symbol--normal + "Function to use rct-complete-symbol.") +;; (setq rct-complete-symbol-function 'rct-complete-symbol--icicles) +(defvar rct-use-test-script t + "Whether rct-complete/rct-doc use test scripts.") + +(defun rct-complete-symbol (&optional option) + "Perform ruby method and class completion on the text around point. +This command only calls a function according to `rct-complete-symbol-function'. +See also `rct-interactive', `rct-complete-symbol--normal', and `rct-complete-symbol--icicles'." + (interactive (rct-interactive)) + (call-interactively rct-complete-symbol-function)) + +(defun rct-complete-symbol--normal (&optional option) + "Perform ruby method and class completion on the text around point. +See also `rct-interactive'." + (interactive (rct-interactive)) + (let ((end (point)) beg + pattern alist + completion) + (setq completion (rct-try-completion)) ; set also pattern / completion + (save-excursion + (search-backward pattern) + (setq beg (point))) + (cond ((eq completion t) ;sole completion + (message "%s" "Sole completion")) + ((null completion) ;no completions + (message "Can't find completion for \"%s\"" pattern) + (ding)) + ((not (string= pattern completion)) ;partial completion + (delete-region beg end) ;delete word + (insert completion) + (message "")) + (t + (message "Making completion list...") + (with-output-to-temp-buffer "*Completions*" + (display-completion-list + (all-completions pattern alist))) + (message "Making completion list...%s" "done"))))) + +;; (define-key ruby-mode-map "\M-\C-i" 'rct-complete-symbol) + +(defun rct-debuglog (logmsg) + "if `rct-debug' is non-nil, output LOGMSG into *Messages*. Returns LOGMSG." + (if rct-debug + (message "%s" logmsg)) + logmsg) + +(defun rct-exec-and-eval (command opt) + "Execute rct-complete/rct-doc and evaluate the output." + (let ((eval-buffer (get-buffer-create " *rct-eval*"))) + ;; copy to temporary buffer to do completion at non-EOL. + (shell-command-on-region + (point-min) (point-max) + (rct-debuglog (format "%s %s %s --line=%d --column=%d %s" + command opt (or rct-option-local "") + (rct-current-line) (current-column) + (if rct-use-test-script (rct-test-script-option-string) ""))) + eval-buffer nil " *rct-error*") + (message "") + (eval (with-current-buffer eval-buffer + (goto-char 1) + (unwind-protect + (read (current-buffer)) + (unless rct-debug (kill-buffer eval-buffer))))))) + +(defun rct-test-script-option-string () + (if (null buffer-file-name) + "" + (let ((test-buf (rct-find-test-script-buffer)) + (bfn buffer-file-name) + t-opt test-filename) + (if test-buf + ;; pass test script's filename and lineno + (with-current-buffer test-buf + (setq t-opt (format "%s@%s" buffer-file-name (rct-current-line))) + (format "-t %s --filename=%s" t-opt bfn)) + "")))) + +(require 'cl) + +(defun rct-find-test-script-buffer (&optional buffer-list) + "Find the latest used Ruby test script buffer." + (setq buffer-list (or buffer-list (buffer-list))) + (dolist (buf buffer-list) + (with-current-buffer buf + (if (and buffer-file-name (string-match "test.*\.rb$" buffer-file-name)) + (return buf))))) + +;; (defun rct-find-test-method (buffer) +;; "Find test method on point on BUFFER." +;; (with-current-buffer buffer +;; (save-excursion +;; (forward-line 1) +;; (if (re-search-backward "^ *def *\\(test_[A-Za-z0-9?!_]+\\)" nil t) +;; (match-string 1))))) + +(defun rct-try-completion () + "Evaluate the output of rct-complete." + (rct-exec-and-eval rct-complete-command-name "--completion-emacs")) + +;;;; TAGS or Ri +(autoload 'ri "ri-ruby" nil t) +(defvar rct-find-tag-if-available t + "If non-nil and the method location is in TAGS, go to the location instead of show documentation.") +(defun rct-ri (&optional option) + "Browse Ri document at the point. +If `rct-find-tag-if-available' is non-nil, search the definition using TAGS. + +See also `rct-interactive'. " + (interactive (rct-interactive)) + (rct-exec-and-eval + rct-doc-command-name + (concat "--ri-emacs --use-method-analyzer " + (if (buffer-file-name) + (concat "--filename=" (buffer-file-name)) + "")))) + +(defun rct-find-tag-or-ri (fullname) + (if (not rct-find-tag-if-available) + (ri fullname) + (condition-case err + (let () + (visit-tags-table-buffer) + (find-tag-in-order (concat "::" fullname) 'search-forward '(tag-exact-match-p) nil "containing" t)) + (error + (ri fullname))))) + +;;;; +(defun ruby-toggle-buffer () + "Open a related file to the current buffer. test<=>impl." + (interactive) + (find-file (shell-command-to-string + (format "%s %s" ruby-toggle-file-command-name buffer-file-name)))) + + +(provide 'rcodetools) diff --git a/Support/vendor/rcodetools-old/rcodetools.vim b/Support/vendor/rcodetools-old/rcodetools.vim new file mode 100644 index 0000000..0796f00 --- /dev/null +++ b/Support/vendor/rcodetools-old/rcodetools.vim @@ -0,0 +1,173 @@ +" Copyright (C) 2006 Mauricio Fernandez +" rcodetools support plugin +" + +if exists("loaded_rcodetools") + finish +endif + +let loaded_rcodetools = 1 +let s:save_cpo = &cpo +set cpo&vim + +"{{{ set s:sid + +map xx xx +let s:sid = maparg("xx") +unmap xx +let s:sid = substitute(s:sid, 'xx', '', '') + +"{{{ function: s:spellgetoption(name, default) +" grab a user-specified option to override the default provided. options are +" searched in the window, buffer, then global spaces. +function! s:GetOption(name, default) + if exists("w:{&filetype}_" . a:name) + execute "return w:{&filetype}_".a:name + elseif exists("w:" . a:name) + execute "return w:".a:name + elseif exists("b:{&filetype}_" . a:name) + execute "return b:{&filetype}_".a:name + elseif exists("b:" . a:name) + execute "return b:".a:name + elseif exists("g:{&filetype}_" . a:name) + execute "return g:{&filetype}_".a:name + elseif exists("g:" . a:name) + execute "return g:".a:name + else + return a:default + endif +endfunction + +"{{{ IsOptionSet +function! s:IsOptionSet(name) + let bogus_val = "df hdsoi3y98 hjsdfhdkj" + return s:GetOption(a:name, bogus_val) == bogus_val ? 0 : 1 +endfunction + + +"{{{ RCT_completion function + +let s:last_test_file = "" +let s:last_test_lineno = 0 + +let s:rct_completion_col = 0 +let s:rct_tmpfile = "" + +function! RCT_command_with_test_options(cmd) + if s:last_test_file != "" + return a:cmd . + \ "-" . "-filename='" . expand("%:p") . "' " . + \ "-t '" . s:last_test_file . "@" . s:last_test_lineno . "' " + endif + return a:cmd +endfunction + +function! RCT_completion(findstart, base) + if a:findstart + let s:rct_completion_col = col('.') - 1 + let s:rct_tmpfile = "tmp-rcodetools" . strftime("Y-%m-%d-%H-%M-%S.rb") + silent exec ":w " . s:rct_tmpfile + return strridx(getline('.'), '.', col('.')) + 1 + else + let line = line('.') + let column = s:rct_completion_col + + let command = "rct-complete --completion-class-info --dev --fork --line=" . + \ line . " --column=" . column . " " + let command = RCT_command_with_test_options(command) . s:rct_tmpfile + + let data = split(system(command), '\n') + + for dline in data + let parts = split(dline, "\t") + let name = get(parts, 0) + let selector = get(parts, 1) + echo name + echo selector + if s:GetOption('rct_completion_use_fri', 0) && s:GetOption('rct_completion_info_max_len', 20) >= len(data) + let fri_data = system('fri -f plain ' . "'" . selector . "'" . ' 2>/dev/null') + call complete_add({'word': name, + \ 'menu': get(split(fri_data), 2, ''), + \ 'info': fri_data } ) + else + call complete_add(name) + endif + if complete_check() + break + endif + endfor + + call delete(s:rct_tmpfile) + return [] + endif +endfunction + +"{{{ ri functions + +function! RCT_new_ri_window() + execute "new" + execute "set bufhidden=delete buftype=nofile noswapfile nobuflisted" + execute 'nmap 2u' + execute 'nmap :call' . s:sid . 'RCT_execute_ri(expand(""))' +endfunction + +function! RCT_execute_ri(query_term) + silent %delete _ + let term = matchstr(a:query_term, '\v[^,.;]+') + let cmd = s:GetOption("RCT_ri_cmd", "fri -f plain ") + let text = system(cmd . "'" . term . "'") + call append(0, split(text, "\n")) + normal gg +endfunction + +function! RCT_find_tag_or_ri(fullname) + " rubikitch: modified for rtags-compatible tags + let tagname = '::' . a:fullname + let tagresults = taglist(tagname) + if len(tagresults) != 0 + execute "tjump " . tagname + else + call RCT_new_ri_window() + call RCT_execute_ri(a:fullname) + endif +endfunction + +function! RCT_smart_ri() + let tmpfile = "tmp-rcodetools" . strftime("Y-%m-%d-%H-%M-%S.rb") + silent exec ":w " . tmpfile + + let line = line('.') + let column = col('.') - 1 + let command = "rct-doc --ri-vim --line=" . line . " --column=" . column . " " + let command = RCT_command_with_test_options(command) . tmpfile + "let term = matchstr(system(command), "\\v[^\n]+") + exec system(command) + call delete(tmpfile) + "call RCT_find_tag_or_ri(term) +endfunction + +function! RCT_ruby_toggle() + let curr_file = expand("%:p") + let cmd = "ruby -S ruby-toggle-file " . curr_file + if match(curr_file, '\v_test|test_') != -1 + let s:last_test_file = curr_file + let s:last_test_lineno = line(".") + endif + let dest = system(cmd) + silent exec ":w" + exec ("edit " . dest) + silent! normal g; +endfunction + +"{{{ bindings and au + +if v:version >= 700 + execute "au Filetype ruby setlocal completefunc=" . s:sid . "RCT_completion" +endif +execute 'au Filetype ruby nmap :exec "call ' . + \ 'RCT_find_tag_or_ri(''" . expand("") . "'')"' +execute 'au Filetype ruby nmap ' . s:GetOption("RCT_ri_binding", "r") . + \ ' :call ' . s:sid . 'RCT_smart_ri()' +execute 'au Filetype ruby nmap ' . s:GetOption("RCT_toggle_binding", "t") . + \ ' :call ' . s:sid . 'RCT_ruby_toggle()' +let &cpo = s:save_cpo diff --git a/Support/vendor/rcodetools-old/setup.rb b/Support/vendor/rcodetools-old/setup.rb new file mode 100644 index 0000000..424a5f3 --- /dev/null +++ b/Support/vendor/rcodetools-old/setup.rb @@ -0,0 +1,1585 @@ +# +# setup.rb +# +# Copyright (c) 2000-2005 Minero Aoki +# +# This program is free software. +# You can distribute/modify this program under the terms of +# the GNU LGPL, Lesser General Public License version 2.1. +# + +unless Enumerable.method_defined?(:map) # Ruby 1.4.6 + module Enumerable + alias map collect + end +end + +unless File.respond_to?(:read) # Ruby 1.6 + def File.read(fname) + open(fname) {|f| + return f.read + } + end +end + +unless Errno.const_defined?(:ENOTEMPTY) # Windows? + module Errno + class ENOTEMPTY + # We do not raise this exception, implementation is not needed. + end + end +end + +def File.binread(fname) + open(fname, 'rb') {|f| + return f.read + } +end + +# for corrupted Windows' stat(2) +def File.dir?(path) + File.directory?((path[-1,1] == '/') ? path : path + '/') +end + + +class ConfigTable + + include Enumerable + + def initialize(rbconfig) + @rbconfig = rbconfig + @items = [] + @table = {} + # options + @install_prefix = nil + @config_opt = nil + @verbose = true + @no_harm = false + end + + attr_accessor :install_prefix + attr_accessor :config_opt + + attr_writer :verbose + + def verbose? + @verbose + end + + attr_writer :no_harm + + def no_harm? + @no_harm + end + + def [](key) + lookup(key).resolve(self) + end + + def []=(key, val) + lookup(key).set val + end + + def names + @items.map {|i| i.name } + end + + def each(&block) + @items.each(&block) + end + + def key?(name) + @table.key?(name) + end + + def lookup(name) + @table[name] or setup_rb_error "no such config item: #{name}" + end + + def add(item) + @items.push item + @table[item.name] = item + end + + def remove(name) + item = lookup(name) + @items.delete_if {|i| i.name == name } + @table.delete_if {|name, i| i.name == name } + item + end + + def load_script(path, inst = nil) + if File.file?(path) + MetaConfigEnvironment.new(self, inst).instance_eval File.read(path), path + end + end + + def savefile + '.config' + end + + def load_savefile + begin + File.foreach(savefile()) do |line| + k, v = *line.split(/=/, 2) + self[k] = v.strip + end + rescue Errno::ENOENT + setup_rb_error $!.message + "\n#{File.basename($0)} config first" + end + end + + def save + @items.each {|i| i.value } + File.open(savefile(), 'w') {|f| + @items.each do |i| + f.printf "%s=%s\n", i.name, i.value if i.value? and i.value + end + } + end + + def load_standard_entries + standard_entries(@rbconfig).each do |ent| + add ent + end + end + + def standard_entries(rbconfig) + c = rbconfig + + rubypath = File.join(c['bindir'], c['ruby_install_name'] + c['EXEEXT']) + + major = c['MAJOR'].to_i + minor = c['MINOR'].to_i + teeny = c['TEENY'].to_i + version = "#{major}.#{minor}" + + # ruby ver. >= 1.4.4? + newpath_p = ((major >= 2) or + ((major == 1) and + ((minor >= 5) or + ((minor == 4) and (teeny >= 4))))) + + if c['rubylibdir'] + # V > 1.6.3 + libruby = "#{c['prefix']}/lib/ruby" + librubyver = c['rubylibdir'] + librubyverarch = c['archdir'] + siteruby = c['sitedir'] + siterubyver = c['sitelibdir'] + siterubyverarch = c['sitearchdir'] + elsif newpath_p + # 1.4.4 <= V <= 1.6.3 + libruby = "#{c['prefix']}/lib/ruby" + librubyver = "#{c['prefix']}/lib/ruby/#{version}" + librubyverarch = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}" + siteruby = c['sitedir'] + siterubyver = "$siteruby/#{version}" + siterubyverarch = "$siterubyver/#{c['arch']}" + else + # V < 1.4.4 + libruby = "#{c['prefix']}/lib/ruby" + librubyver = "#{c['prefix']}/lib/ruby/#{version}" + librubyverarch = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}" + siteruby = "#{c['prefix']}/lib/ruby/#{version}/site_ruby" + siterubyver = siteruby + siterubyverarch = "$siterubyver/#{c['arch']}" + end + parameterize = lambda {|path| + path.sub(/\A#{Regexp.quote(c['prefix'])}/, '$prefix') + } + + if arg = c['configure_args'].split.detect {|arg| /--with-make-prog=/ =~ arg } + makeprog = arg.sub(/'/, '').split(/=/, 2)[1] + else + makeprog = 'make' + end + + [ + ExecItem.new('installdirs', 'std/site/home', + 'std: install under libruby; site: install under site_ruby; home: install under $HOME')\ + {|val, table| + case val + when 'std' + table['rbdir'] = '$librubyver' + table['sodir'] = '$librubyverarch' + when 'site' + table['rbdir'] = '$siterubyver' + table['sodir'] = '$siterubyverarch' + when 'home' + setup_rb_error '$HOME was not set' unless ENV['HOME'] + table['prefix'] = ENV['HOME'] + table['rbdir'] = '$libdir/ruby' + table['sodir'] = '$libdir/ruby' + end + }, + PathItem.new('prefix', 'path', c['prefix'], + 'path prefix of target environment'), + PathItem.new('bindir', 'path', parameterize.call(c['bindir']), + 'the directory for commands'), + PathItem.new('libdir', 'path', parameterize.call(c['libdir']), + 'the directory for libraries'), + PathItem.new('datadir', 'path', parameterize.call(c['datadir']), + 'the directory for shared data'), + PathItem.new('mandir', 'path', parameterize.call(c['mandir']), + 'the directory for man pages'), + PathItem.new('sysconfdir', 'path', parameterize.call(c['sysconfdir']), + 'the directory for system configuration files'), + PathItem.new('localstatedir', 'path', parameterize.call(c['localstatedir']), + 'the directory for local state data'), + PathItem.new('libruby', 'path', libruby, + 'the directory for ruby libraries'), + PathItem.new('librubyver', 'path', librubyver, + 'the directory for standard ruby libraries'), + PathItem.new('librubyverarch', 'path', librubyverarch, + 'the directory for standard ruby extensions'), + PathItem.new('siteruby', 'path', siteruby, + 'the directory for version-independent aux ruby libraries'), + PathItem.new('siterubyver', 'path', siterubyver, + 'the directory for aux ruby libraries'), + PathItem.new('siterubyverarch', 'path', siterubyverarch, + 'the directory for aux ruby binaries'), + PathItem.new('rbdir', 'path', '$siterubyver', + 'the directory for ruby scripts'), + PathItem.new('sodir', 'path', '$siterubyverarch', + 'the directory for ruby extentions'), + PathItem.new('rubypath', 'path', rubypath, + 'the path to set to #! line'), + ProgramItem.new('rubyprog', 'name', rubypath, + 'the ruby program using for installation'), + ProgramItem.new('makeprog', 'name', makeprog, + 'the make program to compile ruby extentions'), + SelectItem.new('shebang', 'all/ruby/never', 'ruby', + 'shebang line (#!) editing mode'), + BoolItem.new('without-ext', 'yes/no', 'no', + 'does not compile/install ruby extentions') + ] + end + private :standard_entries + + def load_multipackage_entries + multipackage_entries().each do |ent| + add ent + end + end + + def multipackage_entries + [ + PackageSelectionItem.new('with', 'name,name...', '', 'ALL', + 'package names that you want to install'), + PackageSelectionItem.new('without', 'name,name...', '', 'NONE', + 'package names that you do not want to install') + ] + end + private :multipackage_entries + + ALIASES = { + 'std-ruby' => 'librubyver', + 'stdruby' => 'librubyver', + 'rubylibdir' => 'librubyver', + 'archdir' => 'librubyverarch', + 'site-ruby-common' => 'siteruby', # For backward compatibility + 'site-ruby' => 'siterubyver', # For backward compatibility + 'bin-dir' => 'bindir', + 'bin-dir' => 'bindir', + 'rb-dir' => 'rbdir', + 'so-dir' => 'sodir', + 'data-dir' => 'datadir', + 'ruby-path' => 'rubypath', + 'ruby-prog' => 'rubyprog', + 'ruby' => 'rubyprog', + 'make-prog' => 'makeprog', + 'make' => 'makeprog' + } + + def fixup + ALIASES.each do |ali, name| + @table[ali] = @table[name] + end + @items.freeze + @table.freeze + @options_re = /\A--(#{@table.keys.join('|')})(?:=(.*))?\z/ + end + + def parse_opt(opt) + m = @options_re.match(opt) or setup_rb_error "config: unknown option #{opt}" + m.to_a[1,2] + end + + def dllext + @rbconfig['DLEXT'] + end + + def value_config?(name) + lookup(name).value? + end + + class Item + def initialize(name, template, default, desc) + @name = name.freeze + @template = template + @value = default + @default = default + @description = desc + end + + attr_reader :name + attr_reader :description + + attr_accessor :default + alias help_default default + + def help_opt + "--#{@name}=#{@template}" + end + + def value? + true + end + + def value + @value + end + + def resolve(table) + @value.gsub(%r<\$([^/]+)>) { table[$1] } + end + + def set(val) + @value = check(val) + end + + private + + def check(val) + setup_rb_error "config: --#{name} requires argument" unless val + val + end + end + + class BoolItem < Item + def config_type + 'bool' + end + + def help_opt + "--#{@name}" + end + + private + + def check(val) + return 'yes' unless val + case val + when /\Ay(es)?\z/i, /\At(rue)?\z/i then 'yes' + when /\An(o)?\z/i, /\Af(alse)\z/i then 'no' + else + setup_rb_error "config: --#{@name} accepts only yes/no for argument" + end + end + end + + class PathItem < Item + def config_type + 'path' + end + + private + + def check(path) + setup_rb_error "config: --#{@name} requires argument" unless path + path[0,1] == '$' ? path : File.expand_path(path) + end + end + + class ProgramItem < Item + def config_type + 'program' + end + end + + class SelectItem < Item + def initialize(name, selection, default, desc) + super + @ok = selection.split('/') + end + + def config_type + 'select' + end + + private + + def check(val) + unless @ok.include?(val.strip) + setup_rb_error "config: use --#{@name}=#{@template} (#{val})" + end + val.strip + end + end + + class ExecItem < Item + def initialize(name, selection, desc, &block) + super name, selection, nil, desc + @ok = selection.split('/') + @action = block + end + + def config_type + 'exec' + end + + def value? + false + end + + def resolve(table) + setup_rb_error "$#{name()} wrongly used as option value" + end + + undef set + + def evaluate(val, table) + v = val.strip.downcase + unless @ok.include?(v) + setup_rb_error "invalid option --#{@name}=#{val} (use #{@template})" + end + @action.call v, table + end + end + + class PackageSelectionItem < Item + def initialize(name, template, default, help_default, desc) + super name, template, default, desc + @help_default = help_default + end + + attr_reader :help_default + + def config_type + 'package' + end + + private + + def check(val) + unless File.dir?("packages/#{val}") + setup_rb_error "config: no such package: #{val}" + end + val + end + end + + class MetaConfigEnvironment + def initialize(config, installer) + @config = config + @installer = installer + end + + def config_names + @config.names + end + + def config?(name) + @config.key?(name) + end + + def bool_config?(name) + @config.lookup(name).config_type == 'bool' + end + + def path_config?(name) + @config.lookup(name).config_type == 'path' + end + + def value_config?(name) + @config.lookup(name).config_type != 'exec' + end + + def add_config(item) + @config.add item + end + + def add_bool_config(name, default, desc) + @config.add BoolItem.new(name, 'yes/no', default ? 'yes' : 'no', desc) + end + + def add_path_config(name, default, desc) + @config.add PathItem.new(name, 'path', default, desc) + end + + def set_config_default(name, default) + @config.lookup(name).default = default + end + + def remove_config(name) + @config.remove(name) + end + + # For only multipackage + def packages + raise '[setup.rb fatal] multi-package metaconfig API packages() called for single-package; contact application package vendor' unless @installer + @installer.packages + end + + # For only multipackage + def declare_packages(list) + raise '[setup.rb fatal] multi-package metaconfig API declare_packages() called for single-package; contact application package vendor' unless @installer + @installer.packages = list + end + end + +end # class ConfigTable + + +# This module requires: #verbose?, #no_harm? +module FileOperations + + def mkdir_p(dirname, prefix = nil) + dirname = prefix + File.expand_path(dirname) if prefix + $stderr.puts "mkdir -p #{dirname}" if verbose? + return if no_harm? + + # Does not check '/', it's too abnormal. + dirs = File.expand_path(dirname).split(%r<(?=/)>) + if /\A[a-z]:\z/i =~ dirs[0] + disk = dirs.shift + dirs[0] = disk + dirs[0] + end + dirs.each_index do |idx| + path = dirs[0..idx].join('') + Dir.mkdir path unless File.dir?(path) + end + end + + def rm_f(path) + $stderr.puts "rm -f #{path}" if verbose? + return if no_harm? + force_remove_file path + end + + def rm_rf(path) + $stderr.puts "rm -rf #{path}" if verbose? + return if no_harm? + remove_tree path + end + + def remove_tree(path) + if File.symlink?(path) + remove_file path + elsif File.dir?(path) + remove_tree0 path + else + force_remove_file path + end + end + + def remove_tree0(path) + Dir.foreach(path) do |ent| + next if ent == '.' + next if ent == '..' + entpath = "#{path}/#{ent}" + if File.symlink?(entpath) + remove_file entpath + elsif File.dir?(entpath) + remove_tree0 entpath + else + force_remove_file entpath + end + end + begin + Dir.rmdir path + rescue Errno::ENOTEMPTY + # directory may not be empty + end + end + + def move_file(src, dest) + force_remove_file dest + begin + File.rename src, dest + rescue + File.open(dest, 'wb') {|f| + f.write File.binread(src) + } + File.chmod File.stat(src).mode, dest + File.unlink src + end + end + + def force_remove_file(path) + begin + remove_file path + rescue + end + end + + def remove_file(path) + File.chmod 0777, path + File.unlink path + end + + def install(from, dest, mode, prefix = nil) + $stderr.puts "install #{from} #{dest}" if verbose? + return if no_harm? + + realdest = prefix ? prefix + File.expand_path(dest) : dest + realdest = File.join(realdest, File.basename(from)) if File.dir?(realdest) + str = File.binread(from) + if diff?(str, realdest) + verbose_off { + rm_f realdest if File.exist?(realdest) + } + File.open(realdest, 'wb') {|f| + f.write str + } + File.chmod mode, realdest + + File.open("#{objdir_root()}/InstalledFiles", 'a') {|f| + if prefix + f.puts realdest.sub(prefix, '') + else + f.puts realdest + end + } + end + end + + def diff?(new_content, path) + return true unless File.exist?(path) + new_content != File.binread(path) + end + + def command(*args) + $stderr.puts args.join(' ') if verbose? + system(*args) or raise RuntimeError, + "system(#{args.map{|a| a.inspect }.join(' ')}) failed" + end + + def ruby(*args) + command config('rubyprog'), *args + end + + def make(task = nil) + command(*[config('makeprog'), task].compact) + end + + def extdir?(dir) + File.exist?("#{dir}/MANIFEST") or File.exist?("#{dir}/extconf.rb") + end + + def files_of(dir) + Dir.open(dir) {|d| + return d.select {|ent| File.file?("#{dir}/#{ent}") } + } + end + + DIR_REJECT = %w( . .. CVS SCCS RCS CVS.adm .svn ) + + def directories_of(dir) + Dir.open(dir) {|d| + return d.select {|ent| File.dir?("#{dir}/#{ent}") } - DIR_REJECT + } + end + +end + + +# This module requires: #srcdir_root, #objdir_root, #relpath +module HookScriptAPI + + def get_config(key) + @config[key] + end + + alias config get_config + + # obsolete: use metaconfig to change configuration + def set_config(key, val) + @config[key] = val + end + + # + # srcdir/objdir (works only in the package directory) + # + + def curr_srcdir + "#{srcdir_root()}/#{relpath()}" + end + + def curr_objdir + "#{objdir_root()}/#{relpath()}" + end + + def srcfile(path) + "#{curr_srcdir()}/#{path}" + end + + def srcexist?(path) + File.exist?(srcfile(path)) + end + + def srcdirectory?(path) + File.dir?(srcfile(path)) + end + + def srcfile?(path) + File.file?(srcfile(path)) + end + + def srcentries(path = '.') + Dir.open("#{curr_srcdir()}/#{path}") {|d| + return d.to_a - %w(. ..) + } + end + + def srcfiles(path = '.') + srcentries(path).select {|fname| + File.file?(File.join(curr_srcdir(), path, fname)) + } + end + + def srcdirectories(path = '.') + srcentries(path).select {|fname| + File.dir?(File.join(curr_srcdir(), path, fname)) + } + end + +end + + +class ToplevelInstaller + + Version = '3.4.1' + Copyright = 'Copyright (c) 2000-2005 Minero Aoki' + + TASKS = [ + [ 'all', 'do config, setup, then install' ], + [ 'config', 'saves your configurations' ], + [ 'show', 'shows current configuration' ], + [ 'setup', 'compiles ruby extentions and others' ], + [ 'install', 'installs files' ], + [ 'test', 'run all tests in test/' ], + [ 'clean', "does `make clean' for each extention" ], + [ 'distclean',"does `make distclean' for each extention" ] + ] + + def ToplevelInstaller.invoke + config = ConfigTable.new(load_rbconfig()) + config.load_standard_entries + config.load_multipackage_entries if multipackage? + config.fixup + klass = (multipackage?() ? ToplevelInstallerMulti : ToplevelInstaller) + klass.new(File.dirname($0), config).invoke + end + + def ToplevelInstaller.multipackage? + File.dir?(File.dirname($0) + '/packages') + end + + def ToplevelInstaller.load_rbconfig + if arg = ARGV.detect {|arg| /\A--rbconfig=/ =~ arg } + ARGV.delete(arg) + load File.expand_path(arg.split(/=/, 2)[1]) + $".push 'rbconfig.rb' + else + require 'rbconfig' + end + ::Config::CONFIG + end + + def initialize(ardir_root, config) + @ardir = File.expand_path(ardir_root) + @config = config + # cache + @valid_task_re = nil + end + + def config(key) + @config[key] + end + + def inspect + "#<#{self.class} #{__id__()}>" + end + + def invoke + run_metaconfigs + case task = parsearg_global() + when nil, 'all' + parsearg_config + init_installers + exec_config + exec_setup + exec_install + else + case task + when 'config', 'test' + ; + when 'clean', 'distclean' + @config.load_savefile if File.exist?(@config.savefile) + else + @config.load_savefile + end + __send__ "parsearg_#{task}" + init_installers + __send__ "exec_#{task}" + end + end + + def run_metaconfigs + @config.load_script "#{@ardir}/metaconfig" + end + + def init_installers + @installer = Installer.new(@config, @ardir, File.expand_path('.')) + end + + # + # Hook Script API bases + # + + def srcdir_root + @ardir + end + + def objdir_root + '.' + end + + def relpath + '.' + end + + # + # Option Parsing + # + + def parsearg_global + while arg = ARGV.shift + case arg + when /\A\w+\z/ + setup_rb_error "invalid task: #{arg}" unless valid_task?(arg) + return arg + when '-q', '--quiet' + @config.verbose = false + when '--verbose' + @config.verbose = true + when '--help' + print_usage $stdout + exit 0 + when '--version' + puts "#{File.basename($0)} version #{Version}" + exit 0 + when '--copyright' + puts Copyright + exit 0 + else + setup_rb_error "unknown global option '#{arg}'" + end + end + nil + end + + def valid_task?(t) + valid_task_re() =~ t + end + + def valid_task_re + @valid_task_re ||= /\A(?:#{TASKS.map {|task,desc| task }.join('|')})\z/ + end + + def parsearg_no_options + unless ARGV.empty? + task = caller(0).first.slice(%r<`parsearg_(\w+)'>, 1) + setup_rb_error "#{task}: unknown options: #{ARGV.join(' ')}" + end + end + + alias parsearg_show parsearg_no_options + alias parsearg_setup parsearg_no_options + alias parsearg_test parsearg_no_options + alias parsearg_clean parsearg_no_options + alias parsearg_distclean parsearg_no_options + + def parsearg_config + evalopt = [] + set = [] + @config.config_opt = [] + while i = ARGV.shift + if /\A--?\z/ =~ i + @config.config_opt = ARGV.dup + break + end + name, value = *@config.parse_opt(i) + if @config.value_config?(name) + @config[name] = value + else + evalopt.push [name, value] + end + set.push name + end + evalopt.each do |name, value| + @config.lookup(name).evaluate value, @config + end + # Check if configuration is valid + set.each do |n| + @config[n] if @config.value_config?(n) + end + end + + def parsearg_install + @config.no_harm = false + @config.install_prefix = '' + while a = ARGV.shift + case a + when '--no-harm' + @config.no_harm = true + when /\A--prefix=/ + path = a.split(/=/, 2)[1] + path = File.expand_path(path) unless path[0,1] == '/' + @config.install_prefix = path + else + setup_rb_error "install: unknown option #{a}" + end + end + end + + def print_usage(out) + out.puts 'Typical Installation Procedure:' + out.puts " $ ruby #{File.basename $0} config" + out.puts " $ ruby #{File.basename $0} setup" + out.puts " # ruby #{File.basename $0} install (may require root privilege)" + out.puts + out.puts 'Detailed Usage:' + out.puts " ruby #{File.basename $0} " + out.puts " ruby #{File.basename $0} [] []" + + fmt = " %-24s %s\n" + out.puts + out.puts 'Global options:' + out.printf fmt, '-q,--quiet', 'suppress message outputs' + out.printf fmt, ' --verbose', 'output messages verbosely' + out.printf fmt, ' --help', 'print this message' + out.printf fmt, ' --version', 'print version and quit' + out.printf fmt, ' --copyright', 'print copyright and quit' + out.puts + out.puts 'Tasks:' + TASKS.each do |name, desc| + out.printf fmt, name, desc + end + + fmt = " %-24s %s [%s]\n" + out.puts + out.puts 'Options for CONFIG or ALL:' + @config.each do |item| + out.printf fmt, item.help_opt, item.description, item.help_default + end + out.printf fmt, '--rbconfig=path', 'rbconfig.rb to load',"running ruby's" + out.puts + out.puts 'Options for INSTALL:' + out.printf fmt, '--no-harm', 'only display what to do if given', 'off' + out.printf fmt, '--prefix=path', 'install path prefix', '' + out.puts + end + + # + # Task Handlers + # + + def exec_config + @installer.exec_config + @config.save # must be final + end + + def exec_setup + @installer.exec_setup + end + + def exec_install + @installer.exec_install + end + + def exec_test + @installer.exec_test + end + + def exec_show + @config.each do |i| + printf "%-20s %s\n", i.name, i.value if i.value? + end + end + + def exec_clean + @installer.exec_clean + end + + def exec_distclean + @installer.exec_distclean + end + +end # class ToplevelInstaller + + +class ToplevelInstallerMulti < ToplevelInstaller + + include FileOperations + + def initialize(ardir_root, config) + super + @packages = directories_of("#{@ardir}/packages") + raise 'no package exists' if @packages.empty? + @root_installer = Installer.new(@config, @ardir, File.expand_path('.')) + end + + def run_metaconfigs + @config.load_script "#{@ardir}/metaconfig", self + @packages.each do |name| + @config.load_script "#{@ardir}/packages/#{name}/metaconfig" + end + end + + attr_reader :packages + + def packages=(list) + raise 'package list is empty' if list.empty? + list.each do |name| + raise "directory packages/#{name} does not exist"\ + unless File.dir?("#{@ardir}/packages/#{name}") + end + @packages = list + end + + def init_installers + @installers = {} + @packages.each do |pack| + @installers[pack] = Installer.new(@config, + "#{@ardir}/packages/#{pack}", + "packages/#{pack}") + end + with = extract_selection(config('with')) + without = extract_selection(config('without')) + @selected = @installers.keys.select {|name| + (with.empty? or with.include?(name)) \ + and not without.include?(name) + } + end + + def extract_selection(list) + a = list.split(/,/) + a.each do |name| + setup_rb_error "no such package: #{name}" unless @installers.key?(name) + end + a + end + + def print_usage(f) + super + f.puts 'Inluded packages:' + f.puts ' ' + @packages.sort.join(' ') + f.puts + end + + # + # Task Handlers + # + + def exec_config + run_hook 'pre-config' + each_selected_installers {|inst| inst.exec_config } + run_hook 'post-config' + @config.save # must be final + end + + def exec_setup + run_hook 'pre-setup' + each_selected_installers {|inst| inst.exec_setup } + run_hook 'post-setup' + end + + def exec_install + run_hook 'pre-install' + each_selected_installers {|inst| inst.exec_install } + run_hook 'post-install' + end + + def exec_test + run_hook 'pre-test' + each_selected_installers {|inst| inst.exec_test } + run_hook 'post-test' + end + + def exec_clean + rm_f @config.savefile + run_hook 'pre-clean' + each_selected_installers {|inst| inst.exec_clean } + run_hook 'post-clean' + end + + def exec_distclean + rm_f @config.savefile + run_hook 'pre-distclean' + each_selected_installers {|inst| inst.exec_distclean } + run_hook 'post-distclean' + end + + # + # lib + # + + def each_selected_installers + Dir.mkdir 'packages' unless File.dir?('packages') + @selected.each do |pack| + $stderr.puts "Processing the package `#{pack}' ..." if verbose? + Dir.mkdir "packages/#{pack}" unless File.dir?("packages/#{pack}") + Dir.chdir "packages/#{pack}" + yield @installers[pack] + Dir.chdir '../..' + end + end + + def run_hook(id) + @root_installer.run_hook id + end + + # module FileOperations requires this + def verbose? + @config.verbose? + end + + # module FileOperations requires this + def no_harm? + @config.no_harm? + end + +end # class ToplevelInstallerMulti + + +class Installer + + FILETYPES = %w( bin lib ext data conf man ) + + include FileOperations + include HookScriptAPI + + def initialize(config, srcroot, objroot) + @config = config + @srcdir = File.expand_path(srcroot) + @objdir = File.expand_path(objroot) + @currdir = '.' + end + + def inspect + "#<#{self.class} #{File.basename(@srcdir)}>" + end + + def noop(rel) + end + + # + # Hook Script API base methods + # + + def srcdir_root + @srcdir + end + + def objdir_root + @objdir + end + + def relpath + @currdir + end + + # + # Config Access + # + + # module FileOperations requires this + def verbose? + @config.verbose? + end + + # module FileOperations requires this + def no_harm? + @config.no_harm? + end + + def verbose_off + begin + save, @config.verbose = @config.verbose?, false + yield + ensure + @config.verbose = save + end + end + + # + # TASK config + # + + def exec_config + exec_task_traverse 'config' + end + + alias config_dir_bin noop + alias config_dir_lib noop + + def config_dir_ext(rel) + extconf if extdir?(curr_srcdir()) + end + + alias config_dir_data noop + alias config_dir_conf noop + alias config_dir_man noop + + def extconf + ruby "#{curr_srcdir()}/extconf.rb", *@config.config_opt + end + + # + # TASK setup + # + + def exec_setup + exec_task_traverse 'setup' + end + + def setup_dir_bin(rel) + files_of(curr_srcdir()).each do |fname| + update_shebang_line "#{curr_srcdir()}/#{fname}" + end + end + + alias setup_dir_lib noop + + def setup_dir_ext(rel) + make if extdir?(curr_srcdir()) + end + + alias setup_dir_data noop + alias setup_dir_conf noop + alias setup_dir_man noop + + def update_shebang_line(path) + return if no_harm? + return if config('shebang') == 'never' + old = Shebang.load(path) + if old + $stderr.puts "warning: #{path}: Shebang line includes too many args. It is not portable and your program may not work." if old.args.size > 1 + new = new_shebang(old) + return if new.to_s == old.to_s + else + return unless config('shebang') == 'all' + new = Shebang.new(config('rubypath')) + end + $stderr.puts "updating shebang: #{File.basename(path)}" if verbose? + open_atomic_writer(path) {|output| + File.open(path, 'rb') {|f| + f.gets if old # discard + output.puts new.to_s + output.print f.read + } + } + end + + def new_shebang(old) + if /\Aruby/ =~ File.basename(old.cmd) + Shebang.new(config('rubypath'), old.args) + elsif File.basename(old.cmd) == 'env' and old.args.first == 'ruby' + Shebang.new(config('rubypath'), old.args[1..-1]) + else + return old unless config('shebang') == 'all' + Shebang.new(config('rubypath')) + end + end + + def open_atomic_writer(path, &block) + tmpfile = File.basename(path) + '.tmp' + begin + File.open(tmpfile, 'wb', &block) + File.rename tmpfile, File.basename(path) + ensure + File.unlink tmpfile if File.exist?(tmpfile) + end + end + + class Shebang + def Shebang.load(path) + line = nil + File.open(path) {|f| + line = f.gets + } + return nil unless /\A#!/ =~ line + parse(line) + end + + def Shebang.parse(line) + cmd, *args = *line.strip.sub(/\A\#!/, '').split(' ') + new(cmd, args) + end + + def initialize(cmd, args = []) + @cmd = cmd + @args = args + end + + attr_reader :cmd + attr_reader :args + + def to_s + "#! #{@cmd}" + (@args.empty? ? '' : " #{@args.join(' ')}") + end + end + + # + # TASK install + # + + def exec_install + rm_f 'InstalledFiles' + exec_task_traverse 'install' + end + + def install_dir_bin(rel) + install_files targetfiles(), "#{config('bindir')}/#{rel}", 0755 + end + + def install_dir_lib(rel) + install_files libfiles(), "#{config('rbdir')}/#{rel}", 0644 + end + + def install_dir_ext(rel) + return unless extdir?(curr_srcdir()) + install_files rubyextentions('.'), + "#{config('sodir')}/#{File.dirname(rel)}", + 0555 + end + + def install_dir_data(rel) + install_files targetfiles(), "#{config('datadir')}/#{rel}", 0644 + end + + def install_dir_conf(rel) + # FIXME: should not remove current config files + # (rename previous file to .old/.org) + install_files targetfiles(), "#{config('sysconfdir')}/#{rel}", 0644 + end + + def install_dir_man(rel) + install_files targetfiles(), "#{config('mandir')}/#{rel}", 0644 + end + + def install_files(list, dest, mode) + mkdir_p dest, @config.install_prefix + list.each do |fname| + install fname, dest, mode, @config.install_prefix + end + end + + def libfiles + glob_reject(%w(*.y *.output), targetfiles()) + end + + def rubyextentions(dir) + ents = glob_select("*.#{@config.dllext}", targetfiles()) + if ents.empty? + setup_rb_error "no ruby extention exists: 'ruby #{$0} setup' first" + end + ents + end + + def targetfiles + mapdir(existfiles() - hookfiles()) + end + + def mapdir(ents) + ents.map {|ent| + if File.exist?(ent) + then ent # objdir + else "#{curr_srcdir()}/#{ent}" # srcdir + end + } + end + + # picked up many entries from cvs-1.11.1/src/ignore.c + JUNK_FILES = %w( + core RCSLOG tags TAGS .make.state + .nse_depinfo #* .#* cvslog.* ,* .del-* *.olb + *~ *.old *.bak *.BAK *.orig *.rej _$* *$ + + *.org *.in .* + ) + + def existfiles + glob_reject(JUNK_FILES, (files_of(curr_srcdir()) | files_of('.'))) + end + + def hookfiles + %w( pre-%s post-%s pre-%s.rb post-%s.rb ).map {|fmt| + %w( config setup install clean ).map {|t| sprintf(fmt, t) } + }.flatten + end + + def glob_select(pat, ents) + re = globs2re([pat]) + ents.select {|ent| re =~ ent } + end + + def glob_reject(pats, ents) + re = globs2re(pats) + ents.reject {|ent| re =~ ent } + end + + GLOB2REGEX = { + '.' => '\.', + '$' => '\$', + '#' => '\#', + '*' => '.*' + } + + def globs2re(pats) + /\A(?:#{ + pats.map {|pat| pat.gsub(/[\.\$\#\*]/) {|ch| GLOB2REGEX[ch] } }.join('|') + })\z/ + end + + # + # TASK test + # + + TESTDIR = 'test' + + def exec_test + unless File.directory?('test') + $stderr.puts 'no test in this package' if verbose? + return + end + $stderr.puts 'Running tests...' if verbose? + begin + require 'test/unit' + rescue LoadError + setup_rb_error 'test/unit cannot loaded. You need Ruby 1.8 or later to invoke this task.' + end + runner = Test::Unit::AutoRunner.new(true) + runner.to_run << TESTDIR + runner.run + end + + # + # TASK clean + # + + def exec_clean + exec_task_traverse 'clean' + rm_f @config.savefile + rm_f 'InstalledFiles' + end + + alias clean_dir_bin noop + alias clean_dir_lib noop + alias clean_dir_data noop + alias clean_dir_conf noop + alias clean_dir_man noop + + def clean_dir_ext(rel) + return unless extdir?(curr_srcdir()) + make 'clean' if File.file?('Makefile') + end + + # + # TASK distclean + # + + def exec_distclean + exec_task_traverse 'distclean' + rm_f @config.savefile + rm_f 'InstalledFiles' + end + + alias distclean_dir_bin noop + alias distclean_dir_lib noop + + def distclean_dir_ext(rel) + return unless extdir?(curr_srcdir()) + make 'distclean' if File.file?('Makefile') + end + + alias distclean_dir_data noop + alias distclean_dir_conf noop + alias distclean_dir_man noop + + # + # Traversing + # + + def exec_task_traverse(task) + run_hook "pre-#{task}" + FILETYPES.each do |type| + if type == 'ext' and config('without-ext') == 'yes' + $stderr.puts 'skipping ext/* by user option' if verbose? + next + end + traverse task, type, "#{task}_dir_#{type}" + end + run_hook "post-#{task}" + end + + def traverse(task, rel, mid) + dive_into(rel) { + run_hook "pre-#{task}" + __send__ mid, rel.sub(%r[\A.*?(?:/|\z)], '') + directories_of(curr_srcdir()).each do |d| + traverse task, "#{rel}/#{d}", mid + end + run_hook "post-#{task}" + } + end + + def dive_into(rel) + return unless File.dir?("#{@srcdir}/#{rel}") + + dir = File.basename(rel) + Dir.mkdir dir unless File.dir?(dir) + prevdir = Dir.pwd + Dir.chdir dir + $stderr.puts '---> ' + rel if verbose? + @currdir = rel + yield + Dir.chdir prevdir + $stderr.puts '<--- ' + rel if verbose? + @currdir = File.dirname(rel) + end + + def run_hook(id) + path = [ "#{curr_srcdir()}/#{id}", + "#{curr_srcdir()}/#{id}.rb" ].detect {|cand| File.file?(cand) } + return unless path + begin + instance_eval File.read(path), path, 1 + rescue + raise if $DEBUG + setup_rb_error "hook #{path} failed:\n" + $!.message + end + end + +end # class Installer + + +class SetupError < StandardError; end + +def setup_rb_error(msg) + raise SetupError, msg +end + +if $0 == __FILE__ + begin + ToplevelInstaller.invoke + rescue SetupError + raise if $DEBUG + $stderr.puts $!.message + $stderr.puts "Try 'ruby #{$0} --help' for detailed usage." + exit 1 + end +end diff --git a/Support/vendor/rcodetools/test/data/add_markers-input.rb b/Support/vendor/rcodetools-old/test/data/add_markers-input.rb similarity index 100% rename from Support/vendor/rcodetools/test/data/add_markers-input.rb rename to Support/vendor/rcodetools-old/test/data/add_markers-input.rb diff --git a/Support/vendor/rcodetools/test/data/add_markers-output.rb b/Support/vendor/rcodetools-old/test/data/add_markers-output.rb similarity index 100% rename from Support/vendor/rcodetools/test/data/add_markers-output.rb rename to Support/vendor/rcodetools-old/test/data/add_markers-output.rb diff --git a/Support/vendor/rcodetools/test/data/bindings-input.rb b/Support/vendor/rcodetools-old/test/data/bindings-input.rb similarity index 100% rename from Support/vendor/rcodetools/test/data/bindings-input.rb rename to Support/vendor/rcodetools-old/test/data/bindings-input.rb diff --git a/Support/vendor/rcodetools/test/data/bindings-output.rb b/Support/vendor/rcodetools-old/test/data/bindings-output.rb similarity index 100% rename from Support/vendor/rcodetools/test/data/bindings-output.rb rename to Support/vendor/rcodetools-old/test/data/bindings-output.rb diff --git a/Support/vendor/rcodetools/test/data/completion-input.rb b/Support/vendor/rcodetools-old/test/data/completion-input.rb similarity index 100% rename from Support/vendor/rcodetools/test/data/completion-input.rb rename to Support/vendor/rcodetools-old/test/data/completion-input.rb diff --git a/Support/vendor/rcodetools/test/data/completion-output.rb b/Support/vendor/rcodetools-old/test/data/completion-output.rb similarity index 100% rename from Support/vendor/rcodetools/test/data/completion-output.rb rename to Support/vendor/rcodetools-old/test/data/completion-output.rb diff --git a/Support/vendor/rcodetools/test/data/completion_emacs-input.rb b/Support/vendor/rcodetools-old/test/data/completion_emacs-input.rb similarity index 100% rename from Support/vendor/rcodetools/test/data/completion_emacs-input.rb rename to Support/vendor/rcodetools-old/test/data/completion_emacs-input.rb diff --git a/Support/vendor/rcodetools/test/data/completion_emacs-output.rb b/Support/vendor/rcodetools-old/test/data/completion_emacs-output.rb similarity index 100% rename from Support/vendor/rcodetools/test/data/completion_emacs-output.rb rename to Support/vendor/rcodetools-old/test/data/completion_emacs-output.rb diff --git a/Support/vendor/rcodetools/test/data/completion_emacs_icicles-input.rb b/Support/vendor/rcodetools-old/test/data/completion_emacs_icicles-input.rb similarity index 100% rename from Support/vendor/rcodetools/test/data/completion_emacs_icicles-input.rb rename to Support/vendor/rcodetools-old/test/data/completion_emacs_icicles-input.rb diff --git a/Support/vendor/rcodetools/test/data/completion_emacs_icicles-output.rb b/Support/vendor/rcodetools-old/test/data/completion_emacs_icicles-output.rb similarity index 100% rename from Support/vendor/rcodetools/test/data/completion_emacs_icicles-output.rb rename to Support/vendor/rcodetools-old/test/data/completion_emacs_icicles-output.rb diff --git a/Support/vendor/rcodetools/test/data/doc-input.rb b/Support/vendor/rcodetools-old/test/data/doc-input.rb similarity index 100% rename from Support/vendor/rcodetools/test/data/doc-input.rb rename to Support/vendor/rcodetools-old/test/data/doc-input.rb diff --git a/Support/vendor/rcodetools/test/data/doc-output.rb b/Support/vendor/rcodetools-old/test/data/doc-output.rb similarity index 100% rename from Support/vendor/rcodetools/test/data/doc-output.rb rename to Support/vendor/rcodetools-old/test/data/doc-output.rb diff --git a/Support/vendor/rcodetools-old/test/data/method_analyzer-data.rb b/Support/vendor/rcodetools-old/test/data/method_analyzer-data.rb new file mode 100644 index 0000000..82fca08 --- /dev/null +++ b/Support/vendor/rcodetools-old/test/data/method_analyzer-data.rb @@ -0,0 +1,33 @@ + +class A + def A.foo + 1 + end + + def a + 1+1 + end +end +class B < A + def initialize + end + attr_accessor :bb + + def b + "a".length + end +end +tm = Time.now +[tm.year, tm.month, tm.day] << 0 +a = A.new +a.a +b = B.new +b.a +b.b +[b.a,b.b] +z = b.a + b.b +A.foo +B.foo +b.bb=1 +b.bb + diff --git a/Support/vendor/rcodetools-old/test/data/method_args.data.rb b/Support/vendor/rcodetools-old/test/data/method_args.data.rb new file mode 100644 index 0000000..b95fa83 --- /dev/null +++ b/Support/vendor/rcodetools-old/test/data/method_args.data.rb @@ -0,0 +1,106 @@ +# method_args.data.rb +class FixedArgsMethods + def self.singleton(a1) end + def initialize(arg) end + def f(a1) end + def b(a1,&block) end + define_method(:defmethod) {|a1|} + attr_accessor :by_attr_accessor + attr :by_attr_false + attr :by_attr_true, true + attr_reader :by_attr_reader_1, :by_attr_reader_2 + attr_writer :by_attr_writer + def private_meth(x) end + private :private_meth + class << self + attr_accessor :singleton_attr_accessor + define_method(:singleton_defmethod){|a2|} + end +end + +module VariableArgsMethods + def s(a1,*splat) end + def sb(a1,*splat, &block) end + def d(a1,default=nil) end + def ds(a1,default=nil,*splat) end + def dsb(a1,default=nil,*splat,&block) end + def db(a1,default=nil,&block) end +end + +class Fixnum + def method_in_Fixnum(arg1, arg2) end + def self.singleton_method_in_Fixnum(arg1, arg2) end +end +class Bignum + def method_in_Bignum(arg1, arg2) end +end +class Float + def method_in_Float(arg1, arg2) end +end +class Symbol + def method_in_Symbol(arg1, arg2) end +end +class Binding + def method_in_Binding(arg1, arg2) end +end +class UnboundMethod + def method_in_UnboundMethod(arg1, arg2) end +end +class Method + def method_in_Method(arg1, arg2) end +end +class Proc + def method_in_Proc(arg1, arg2) end +end +class Continuation + def method_in_Continuation(arg1, arg2) end +end +class Thread + def method_in_Thread(arg1, arg2) end +end +# FIXME mysterious +# class FalseClass +# def method_in_FalseClass(arg1, arg2) end +# end +class TrueClass + def method_in_TrueClass(arg1, arg2) end +end +class NilClass + def method_in_NilClass(arg1, arg2) end +end +class Struct + def method_in_Struct(arg1, arg2) end +end + +require 'digest' +class Digest::Base + def method_in_Digest_Base(arg1, arg2) end +end + +class AnAbstractClass + $__method_args_off = true + def self.allocate + raise NotImplementedError, "#{self} is an abstract class." + end + $__method_args_off = false + + def method_in_AnAbstractClass(arg1, arg2) + end + +end + +class AClass + include VariableArgsMethods + extend VariableArgsMethods +end + +class ASubClass < AClass +end + +StructA = Struct.new :a, :b +class SubclassOfStructA < StructA + attr :method_in_b +end +class StructSubclass < Struct.new(:c) + attr :method_in_c +end diff --git a/Support/vendor/rcodetools/test/data/no_warnings-input.rb b/Support/vendor/rcodetools-old/test/data/no_warnings-input.rb similarity index 100% rename from Support/vendor/rcodetools/test/data/no_warnings-input.rb rename to Support/vendor/rcodetools-old/test/data/no_warnings-input.rb diff --git a/Support/vendor/rcodetools/test/data/no_warnings-output.rb b/Support/vendor/rcodetools-old/test/data/no_warnings-output.rb similarity index 100% rename from Support/vendor/rcodetools/test/data/no_warnings-output.rb rename to Support/vendor/rcodetools-old/test/data/no_warnings-output.rb diff --git a/Support/vendor/rcodetools/test/data/refe-input.rb b/Support/vendor/rcodetools-old/test/data/refe-input.rb similarity index 100% rename from Support/vendor/rcodetools/test/data/refe-input.rb rename to Support/vendor/rcodetools-old/test/data/refe-input.rb diff --git a/Support/vendor/rcodetools/test/data/refe-output.rb b/Support/vendor/rcodetools-old/test/data/refe-output.rb similarity index 100% rename from Support/vendor/rcodetools/test/data/refe-output.rb rename to Support/vendor/rcodetools-old/test/data/refe-output.rb diff --git a/Support/vendor/rcodetools/test/data/ri-input.rb b/Support/vendor/rcodetools-old/test/data/ri-input.rb similarity index 100% rename from Support/vendor/rcodetools/test/data/ri-input.rb rename to Support/vendor/rcodetools-old/test/data/ri-input.rb diff --git a/Support/vendor/rcodetools/test/data/ri-output.rb b/Support/vendor/rcodetools-old/test/data/ri-output.rb similarity index 100% rename from Support/vendor/rcodetools/test/data/ri-output.rb rename to Support/vendor/rcodetools-old/test/data/ri-output.rb diff --git a/Support/vendor/rcodetools/test/data/ri_emacs-input.rb b/Support/vendor/rcodetools-old/test/data/ri_emacs-input.rb similarity index 100% rename from Support/vendor/rcodetools/test/data/ri_emacs-input.rb rename to Support/vendor/rcodetools-old/test/data/ri_emacs-input.rb diff --git a/Support/vendor/rcodetools/test/data/ri_emacs-output.rb b/Support/vendor/rcodetools-old/test/data/ri_emacs-output.rb similarity index 100% rename from Support/vendor/rcodetools/test/data/ri_emacs-output.rb rename to Support/vendor/rcodetools-old/test/data/ri_emacs-output.rb diff --git a/Support/vendor/rcodetools/test/data/ri_vim-input.rb b/Support/vendor/rcodetools-old/test/data/ri_vim-input.rb similarity index 100% rename from Support/vendor/rcodetools/test/data/ri_vim-input.rb rename to Support/vendor/rcodetools-old/test/data/ri_vim-input.rb diff --git a/Support/vendor/rcodetools/test/data/ri_vim-output.rb b/Support/vendor/rcodetools-old/test/data/ri_vim-output.rb similarity index 100% rename from Support/vendor/rcodetools/test/data/ri_vim-output.rb rename to Support/vendor/rcodetools-old/test/data/ri_vim-output.rb diff --git a/Support/vendor/rcodetools/test/data/rspec-input.rb b/Support/vendor/rcodetools-old/test/data/rspec-input.rb similarity index 100% rename from Support/vendor/rcodetools/test/data/rspec-input.rb rename to Support/vendor/rcodetools-old/test/data/rspec-input.rb diff --git a/Support/vendor/rcodetools/test/data/rspec-output.rb b/Support/vendor/rcodetools-old/test/data/rspec-output.rb similarity index 100% rename from Support/vendor/rcodetools/test/data/rspec-output.rb rename to Support/vendor/rcodetools-old/test/data/rspec-output.rb diff --git a/Support/vendor/rcodetools/test/data/rspec_poetry-input.rb b/Support/vendor/rcodetools-old/test/data/rspec_poetry-input.rb similarity index 100% rename from Support/vendor/rcodetools/test/data/rspec_poetry-input.rb rename to Support/vendor/rcodetools-old/test/data/rspec_poetry-input.rb diff --git a/Support/vendor/rcodetools/test/data/rspec_poetry-output.rb b/Support/vendor/rcodetools-old/test/data/rspec_poetry-output.rb similarity index 100% rename from Support/vendor/rcodetools/test/data/rspec_poetry-output.rb rename to Support/vendor/rcodetools-old/test/data/rspec_poetry-output.rb diff --git a/Support/vendor/rcodetools/test/data/simple_annotation-input.rb b/Support/vendor/rcodetools-old/test/data/simple_annotation-input.rb similarity index 100% rename from Support/vendor/rcodetools/test/data/simple_annotation-input.rb rename to Support/vendor/rcodetools-old/test/data/simple_annotation-input.rb diff --git a/Support/vendor/rcodetools/test/data/simple_annotation-output.rb b/Support/vendor/rcodetools-old/test/data/simple_annotation-output.rb similarity index 100% rename from Support/vendor/rcodetools/test/data/simple_annotation-output.rb rename to Support/vendor/rcodetools-old/test/data/simple_annotation-output.rb diff --git a/Support/vendor/rcodetools/test/data/unit_test-input.rb b/Support/vendor/rcodetools-old/test/data/unit_test-input.rb similarity index 100% rename from Support/vendor/rcodetools/test/data/unit_test-input.rb rename to Support/vendor/rcodetools-old/test/data/unit_test-input.rb diff --git a/Support/vendor/rcodetools/test/data/unit_test-output.rb b/Support/vendor/rcodetools-old/test/data/unit_test-output.rb similarity index 100% rename from Support/vendor/rcodetools/test/data/unit_test-output.rb rename to Support/vendor/rcodetools-old/test/data/unit_test-output.rb diff --git a/Support/vendor/rcodetools/test/data/unit_test_poetry-input.rb b/Support/vendor/rcodetools-old/test/data/unit_test_poetry-input.rb similarity index 100% rename from Support/vendor/rcodetools/test/data/unit_test_poetry-input.rb rename to Support/vendor/rcodetools-old/test/data/unit_test_poetry-input.rb diff --git a/Support/vendor/rcodetools/test/data/unit_test_poetry-output.rb b/Support/vendor/rcodetools-old/test/data/unit_test_poetry-output.rb similarity index 100% rename from Support/vendor/rcodetools/test/data/unit_test_poetry-output.rb rename to Support/vendor/rcodetools-old/test/data/unit_test_poetry-output.rb diff --git a/Support/vendor/rcodetools-old/test/test_completion.rb b/Support/vendor/rcodetools-old/test/test_completion.rb new file mode 100644 index 0000000..54d87ec --- /dev/null +++ b/Support/vendor/rcodetools-old/test/test_completion.rb @@ -0,0 +1,640 @@ +$: << ".." << "../lib" +require 'rcodetools/completion' +require 'test/unit' + +class TestXMPCompletionFilter < Test::Unit::TestCase + def doit(code, lineno, column=nil, options={}) + xmp = XMPCompletionFilter.new options + xmp.candidates(code, lineno, column).sort + end + + def test_complete_method__simple + assert_equal(["length"], doit('"a".lengt', 1)) + assert_equal(["length"], doit('`echo a`.lengt', 1)) + end + + def test_complete_method__in_arg + assert_equal(["length"], doit('print("a".lengt)', 1, 15)) + assert_equal(["length"], doit("print('a'.lengt)", 1, 15)) + assert_equal(["length"], doit("((a, b = 1 + 'a'.lengt))", 1, 22)) + end + + def test_complete_method__in_method + assert_equal(["length"], doit(<true)) + module X + xx # normally NoMethodError + module_funct + end +EOC + end + + # drawback of ignore_NoMethodError + def test_with_or_without_ignore_NoMethodError + code = <true)) + end + + def test__syntax_error + assert_raise(ProcessParticularLine::NewCodeError) do + doit(< == === =~ > >= < <= << >> + + - * / % ** ~ + ].each do |op| + ancestors_re = Fixnum.ancestors.map{|x|x.to_s}.join('|') + assert_match(/^#{ancestors_re}##{Regexp.quote(op)}$/, doit("1 #{op} 2",1,2)) + end + end + + def test_aref_aset__Array + assert_equal("Array#[]", doit("[0][ 0 ]",1,4)) + assert_equal("Array#[]=", doit("[0][ 0 ]=10",1,4)) + assert_equal("Array#[]", doit("[0][0]",1,4)) + assert_equal("Array#[]=", doit("[0][0]=10",1,4)) + end + + def test_aref_aset__Object + assert_equal("Array#[]", doit("Array.new(3)[ 0 ]",1,13)) + assert_equal("Array#[]=", doit("Array.new(3)[ 0 ]=10",1,13)) + assert_equal("Array#[]", doit("Array.new(3)[0]",1,13)) + assert_equal("Array#[]=", doit("Array.new(3)[0]=10",1,13)) + end + + def test_aref_aset__Fixnum + assert_equal("Fixnum#[]", doit("0[ 0 ]",1,2)) + assert_equal("Fixnum#[]", doit("0[0]",1,2)) + end + + def test_aref_aset__String + assert_equal("String#[]", doit("'a' + '[0]'[ 0 ]",1,12)) + assert_equal("String#[]", doit("'[0]'[ 0 ]",1,6)) + assert_equal("String#[]=", doit("'0'[ 0 ]=10",1,4)) + assert_equal("String#[]", doit("'[0]'[0]",1,6)) + assert_equal("String#[]=", doit("'0'[0]=10",1,4)) + end + + def test_phrase + assert_equal("Array#uniq", doit('Array.new(3).uniq',1)) + assert_equal("Array#uniq", doit('Array.new(3).to_a.uniq',1)) + assert_equal("Array#uniq", doit('Array.new(3).map{|x| x.to_i}.uniq',1)) + assert_equal("Array#uniq", doit('[][0,(1+1)].uniq',1)) + end + + def test_percent__String + assert_equal("String#length", doit('%!foo!.length',1)) + assert_equal("String#length", doit('%q!foo!.length',1)) + assert_equal("String#length", doit('%Q!foo!.length',1)) + assert_equal("String#length", doit('%x!foo!.length',1)) + + assert_equal("String#length", doit('%{foo}.length',1)) + assert_equal("String#length", doit('%q{foo}.length',1)) + assert_equal("String#length", doit('%q!(!.length',1)) + assert_equal("String#length", doit('%Q!(!.length',1)) + assert_equal("String#length", doit('%x!(!.length',1)) + assert_equal("String#length", doit('%x{(}.length',1)) + + assert_equal("String#length", doit('%{f(o)o}.length',1)) + assert_equal("String#length", doit('%{f{o}o}.length',1)) + assert_equal("String#length", doit('(%{f{o}o}+%!}x!).length',1)) + end + + def test_percent__Array + assert_equal("Array#length", doit('%w!foo!.length',1)) + assert_equal("Array#length", doit('%W!foo!.length',1)) + + assert_equal("Array#length", doit('%w{foo}.length',1)) + assert_equal("Array#length", doit('%W{foo}.length',1)) + assert_equal("Array#length", doit('%w!(!.length',1)) + assert_equal("Array#length", doit('%W!(!.length',1)) + assert_equal("Array#length", doit('%w{(}.length',1)) + + assert_equal("Array#length", doit('%w{f(o)o}.length',1)) + assert_equal("Array#length", doit('%w{f{o}o}.length',1)) + assert_equal("Array#length", doit('(%W{f{o}o}+%w!}x!).length',1)) + end + + def test_percent__Regexp + assert_equal("Regexp#kcode", doit('%r!foo!.kcode',1)) + assert_equal("Regexp#kcode", doit('%r{foo}.kcode',1)) + assert_equal("Regexp#kcode", doit('%r!(!.kcode',1)) + assert_equal("Regexp#kcode", doit('%r[(].kcode',1)) + assert_equal("Regexp#kcode", doit('%r.kcode',1)) + end + + def test_percent__Symbol + assert_equal("Symbol#id2name", doit('%s!foo!.id2name',1)) + assert_equal("Symbol#id2name", doit('%s{foo}.id2name',1)) + assert_equal("Symbol#id2name", doit('%s!(!.id2name',1)) + assert_equal("Symbol#id2name", doit('%s{(}.id2name',1)) + assert_equal("Symbol#id2name", doit('%s(f(o)o).id2name',1)) + end + + def test_bare_word__with_NoMethodError + assert_equal("Module#module_function", doit(<true)) + module X + xx # normally NoMethodError + module_function + end +EOC + end + + def test__syntax_error + assert_raise(ProcessParticularLine::NewCodeError) do + doit(< [], :unit_test => ["-u"], :rspec => ["-s"], + :no_warnings => ["--no-warnings"], :bindings => ["--poetry", "-u"], + :add_markers => ["-m"] + } + tests.each_pair do |test, opts| + define_method("test_#{test}") do + dir = File.expand_path(File.dirname(__FILE__)) + libdir = File.expand_path(dir + '/../lib') + exec = File.expand_path(dir + '/../bin/xmpfilter') + output = `ruby -I#{libdir} #{exec} #{opts.join(" ")} #{dir}/data/#{test}-input.rb` + outputfile = "#{dir}/data/#{test}-output.rb" + assert_equal(File.read(outputfile), output) + end + end +end diff --git a/Support/vendor/rcodetools-old/test/test_method_analyzer.rb b/Support/vendor/rcodetools-old/test/test_method_analyzer.rb new file mode 100644 index 0000000..f40d69b --- /dev/null +++ b/Support/vendor/rcodetools-old/test/test_method_analyzer.rb @@ -0,0 +1,99 @@ +require 'test/unit' + +module ScriptConfig + DIR = File.join(File.expand_path(File.dirname(__FILE__))) + SCRIPT = File.join(DIR, "..", "lib", "method_analyzer.rb") + DATAFILE = File.join(DIR, "data", "method_analyzer-data.rb") +end + +class MethodAnalyzerTextOutput < Test::Unit::TestCase + include ScriptConfig + +# test (find-sh "ruby -r../method_analyzer data/method_analyzer-data.rb") + + # attr_accessor is actually Module#attr_accessor. + # But `f?ri Module.attr_accessor' answers correctly. + expected = < < Struct +method_args.data.rb:101:class SubclassOfStructA < StructA +method_args.data.rb:102:SubclassOfStructA#method_in_b +method_args.data.rb:104:class < Struct +method_args.data.rb:104:class StructSubclass < +method_args.data.rb:105:StructSubclass#method_in_c +XXX + + # To avoid dependency of pwd. + module StripDir + def strip_dir! + slice! %r!^.*/! + self + end + end + + @@expected.each do |line| + begin + file_lineno_klass_meth, rest = line.split(/\s+/,2) + if file_lineno_klass_meth =~ /:/ + file, lineno, klass_meth = file_lineno_klass_meth.split(/:/) + klass_meth = rest if %w[class include extend].include? klass_meth + else # filename/lineno is unknown + klass_meth = file_lineno_klass_meth + end + + test_method_name = "test_" + klass_meth + define_method(test_method_name) do + actual = @@result.grep(/#{klass_meth}/)[0].extend(StripDir).strip_dir! + assert_equal line, actual + end + rescue Exception + end + end + + def test_all_tests + assert_equal @@expected.length, @@result.length, @@result.join("\n") + end + + def test_without_n_option + first_line = "FixedArgsMethods.singleton (a1)" + command_output = `ruby '#{SCRIPT}' '#{DATAFILE}'` + assert_match(/\A#{Regexp.quote(first_line)}\n/, command_output) + end +end + + +class TestTAGS < Test::Unit::TestCase + include MethodArgsScriptConfig + + @@TAGS = `ruby '#{SCRIPT}' -t '#{DATAFILE}'` + def test_filename + # check whether full path is passed. + assert_match %r!^\cl\n/.+method_args.data.rb,\d!, @@TAGS + end + + def test_singleton_method + # including line/byte test + assert @@TAGS.include?(" def self.singleton(a1) end::FixedArgsMethods.singleton3,45") + end + + def test_instance_method + assert @@TAGS.include?(" def initialize(arg) end::FixedArgsMethods#initialize4,74") + end + + def test_include + assert_match(/^ include VariableArgsMethods::AClass/, @@TAGS) + end + + def test_extend + assert_match(/^ extend VariableArgsMethods::AClass/, @@TAGS) + end + + def test_inheritance + assert_match(/^class ASubClass < AClass::ASubClass/, @@TAGS) + end +end diff --git a/Support/vendor/rcodetools-old/test/test_options.rb b/Support/vendor/rcodetools-old/test/test_options.rb new file mode 100644 index 0000000..33a2020 --- /dev/null +++ b/Support/vendor/rcodetools-old/test/test_options.rb @@ -0,0 +1,32 @@ +$: << ".." << "../lib" +require 'rcodetools/options' +require 'test/unit' +require 'tmpdir' +require 'fileutils' + +class TestOptionHandler < Test::Unit::TestCase + include OptionHandler + + def include_paths_check + options = { :include_paths => [] } + auto_include_paths options[:include_paths], Dir.pwd + assert options[:include_paths].include?("#{@basedir}/lib") + assert options[:include_paths].include?("#{@basedir}/bin") + end + + def test_auto_include_paths + Dir.chdir(Dir.tmpdir) do + begin + FileUtils.mkdir_p ["project", "project/lib/project", "project/bin", "project/share"] + open("project/Rakefile","w"){} + @basedir = File.expand_path "project" + Dir.chdir("project/lib/project/") { include_paths_check } + Dir.chdir("project/lib/") { include_paths_check } + Dir.chdir("project/bin/") { include_paths_check } + Dir.chdir("project/") { include_paths_check } + ensure + FileUtils.rm_rf "project" + end + end + end +end diff --git a/Support/vendor/rcodetools/test/test_run.rb b/Support/vendor/rcodetools-old/test/test_run.rb similarity index 100% rename from Support/vendor/rcodetools/test/test_run.rb rename to Support/vendor/rcodetools-old/test/test_run.rb diff --git a/Support/vendor/rcodetools-old/test/test_xmpfilter.rb b/Support/vendor/rcodetools-old/test/test_xmpfilter.rb new file mode 100644 index 0000000..95ca5e6 --- /dev/null +++ b/Support/vendor/rcodetools-old/test/test_xmpfilter.rb @@ -0,0 +1,36 @@ + +require 'test/unit' +$: << ".." << "../lib[s]" +require "rcodetools/xmpfilter" + +class TestXMPFilter < Test::Unit::TestCase + def setup + @xmp = XMPFilter.new + @marker = XMPFilter::MARKER + end + + def test_extract_data + str = <<-EOF +#{@marker}[1] => Fixnum 42 +#{@marker}[1] => Fixnum 0 +#{@marker}[1] ==> var +#{@marker}[1] ==> var2 +#{@marker}[4] ==> var3 +#{@marker}[2] ~> some exception +#{@marker}[10] => Fixnum 42 + EOF + data = @xmp.extract_data(str) + assert_kind_of(XMPFilter::RuntimeData, data) + assert_equal([[1, [["Fixnum", "42"], ["Fixnum", "0"]]], [10, [["Fixnum", "42"]]]], data.results.sort) + assert_equal([[2, ["some exception"]]], data.exceptions.sort) + assert_equal([[1, ["var", "var2"]], [4, ["var3"]]], data.bindings.sort) + end +end + +class TestXMPAddMarkers < Test::Unit::TestCase + + + def test_ + + end +end diff --git a/Support/vendor/rcodetools-old/test/test_xmptestunitfilter.rb b/Support/vendor/rcodetools-old/test/test_xmptestunitfilter.rb new file mode 100644 index 0000000..adadc82 --- /dev/null +++ b/Support/vendor/rcodetools-old/test/test_xmptestunitfilter.rb @@ -0,0 +1,84 @@ + +require 'test/unit' +$: << ".." << "../lib" +require "rcodetools/xmptestunitfilter" + +class TestXMPTestUnitFilter < Test::Unit::TestCase + def setup + @xmp = XMPTestUnitFilter.new + end + + ANNOTATION_VAR_INFERENCE_INPUT = < +arr.last # \=> +EOF + ANNOTATION_VAR_INFERENCE_OUTPUT = <]\", arr.inspect) +assert_equal(x, arr.last) +assert_kind_of(X, arr.last) +assert_equal(\"#\", arr.last.inspect) +EOF + + def test_annotation_var_inference + assert_equal(ANNOTATION_VAR_INFERENCE_OUTPUT, + @xmp.annotate(ANNOTATION_VAR_INFERENCE_INPUT).join("")) + end + + def test_equality_assertions + assert_equal(["a = 1\n", "assert_equal(1, a)"], @xmp.annotate("a = 1\na # \=>")) + assert_equal(["a = {1,2}\n", "assert_equal({1=>2}, a)"], + @xmp.annotate("a = {1,2}\na # \=>")) + assert_equal(["a = [1,2]\n", "assert_equal([1, 2], a)"], + @xmp.annotate("a = [1,2]\na # \=>")) + assert_equal(["a = 'foo'\n", "assert_equal(\"foo\", a)"], + @xmp.annotate("a = 'foo'\na # \=>")) + assert_equal(["a = 1.0\n", "assert_in_delta(1.0, a, 0.0001)"], + @xmp.annotate("a = 1.0\na # \=>")) + end + + def test_raise_assertion + code = < +EOF + assert_equal(["class NoGood < Exception; end\n", + "assert_raise(NoGood){raise NoGood}\n"], @xmp.annotate(code)) + end + + def test_assert_nil + assert_equal(["a = nil\n", "assert_nil(a)"], @xmp.annotate("a = nil\na # \=>")) + end + + def test_poetry_mode + code = < +a = 1.0 +a # \=> +raise "foo" # \=> +a = nil +a # \=> +EOF + output = < false) + assert_equal(output, xmp.annotate(code).join) + end +end diff --git a/Support/vendor/rcodetools/CHANGES b/Support/vendor/rcodetools/CHANGES index 57056ba..98d7f3c 100644 --- a/Support/vendor/rcodetools/CHANGES +++ b/Support/vendor/rcodetools/CHANGES @@ -1,5 +1,25 @@ rcodetools history ================== +User-visible changes since 0.8.4 +-------------------------------- +* OOPS, added missing files. + +User-visible changes since 0.8.0 +-------------------------------- +* xmpfilter: fixed multi-line annotation bugs + +User-visible changes since 0.7.0 +-------------------------------- +* Support Ruby 1.9! +* xmpfilter: multi-line annotation +* xmpfilter --expectations generates expectations by Jay Fields +* anything-rcodetools.el: new elisp +* --tmpfile, --tempfile: use temporary file instead of open3 on un*x +* rcodetools.el: smarter xmpfilter-command +* rcodetools.el: rct-fork interface +* rct-fork: require 'rubygems' initially +* rct-fork: more stable + User-visible changes since 0.5.0 -------------------------------- * "test-driven completion" (TDC) support for Emacs and vim (see README.TDC) diff --git a/Support/vendor/rcodetools/README b/Support/vendor/rcodetools/README index 38434ec..036373f 100644 --- a/Support/vendor/rcodetools/README +++ b/Support/vendor/rcodetools/README @@ -1,7 +1,7 @@ rcodetools http://eigenclass.org/hiki.rb?rcodetools Copyright (c) 2005-2007 Mauricio Fernandez http://eigenclass.org - Copyright (c) 2006-2007 rubikitch http://www.rubyist.net/~rubikitch/ + Copyright (c) 2006-2008 rubikitch http://www.rubyist.net/~rubikitch/ Use and distribution subject to the terms of the Ruby license. = Overview diff --git a/Support/vendor/rcodetools/README.TDC b/Support/vendor/rcodetools/README.TDC new file mode 100644 index 0000000..5a413da --- /dev/null +++ b/Support/vendor/rcodetools/README.TDC @@ -0,0 +1,158 @@ + += Overview + +Ruby is very dynamic language, therefore it is impossible to do +accurate completion without executing script. While executing script +from start to cursor point is often dangerous, executing unit test +script covering current point is SAFE. I call this methodology +`Test-Driven Completion' (TDC). + +As I have already stated in README, browsing documentation of method +(rct-doc) is almost identical operation to completion. This +discussion is applicable to rct-doc. + += Why TDD Is Needed + +In the following code snippet: + + File.unlink a_file + File. <- + +If you complete after `File.', rct-complete actually deletes a_file. +Normally it is unpleasant. +In real-life development, side-effect is inevitable. + +In the foo method which are not called: + + def foo + 1. <- + end + +If the code does not call foo, rct-complete cannot do any completions. +Before TDC, if you want to do completion in methods, you have to write +method call and remove it after completion. Too useless!! + += Messianic Unit Test Script + +Recently Test-Driven Development (TDD) is widespread. Many developers +write unit tests. Fortunately Ruby's unit tester, Test::Unit, is +sophisticated enough to test one test method. Unit tests are +self-enclosed: they must tear down resources, so executing unit tests +are SAFE. TDC uses unit test to do completion. + += TDC Methodology + +(1) Switch to unit test script. +(2) Write a test for target method. +(3) Switch to implementation script. +(4) You can write target method WITH COMPLETION! +(5) Back to (1) + +TDC methodology is almost identical to TDD. TDC is very easy for TDDers. + += TDC With Example + +For simplicity, suppose that you are unfamiliar with Time class and +you want to write a method to format date string. + +The directory structure and file contents is following: + + /tmp/mylib0/ + /tmp/mylib0/lib/ + mylib0.rb + /tmp/mylib0/test/ + test_mylib0.rb + + List: mylib0.rb + # contrived example of long-runtime method + def mysleep(x) + sleep x + end + + def mytime(tm) + + end + + + List: test_mylib0.rb + require 'test/unit' + require 'mylib0' + class TestMylib0 < Test::Unit::TestCase + def test_0_mysleep + s = Time.now + mysleep 3.0 + e = Time.now + assert_in_delta 3.0, e-s, 0.01 + end + + def test_1_mytime + + end + end + +These sample files are in demo/ directory. + + +== Switch to unit test script. + +TDC starts with writing unit test as TDD does. +Open test_mylib0.rb. + +== Write a test for target method. + +Suppose that you want to write mytime method and test_1_mytime test +method, and that you want to experiment Time class first (before +forming an assertion). + +In TDC, you do not have to write an assertion first: just write only a +method call. If you are familiar with Time class, you are free to +write an assertion, of course. + + def test_1_mytime + mytime(Time.now) + end + +At this time, the cursor position is in test_1_mytime test method. + +== Switch to implementation script. + +Open mylib0.rb with the `ruby-toggle-file' script. For example, in Emacs use +the `ruby-toggle-buffer' command, and in vim the t (by default +\t) binding. Since in TDD/TDC you often switch between the test and the +implementation, it is much handier than typing the filename manually. + +The rct-complete uses latest-selected test script as TDC test script +and test method at cursor position as TDC test method. In this case, +test_mylib0.rb is TDC test script and test_1_mytime is TDC test +method. If the cursor position of test_mylib0.rb is at the top, +rct-complete executes whole test methods in test_mylib0.rb. Therefore +latency of completion is longer. + +== You can write target method WITH COMPLETION! + +Fill mytime method. + + def mytime(tm) + tm. + end + +Do completion after `tm.'. Here! Your editor is listing methods `tm' +accepts!! If your editor has help-on-candidate mechanism (eg. Emacs + +Icicles), you would see documentation of each listed method. + +Then you find `Time#strftime' method. Type `str' and do completion. + + def mytime(tm) + tm.strftime + end + +Usage is... use `rct-doc' (in Emacs, `rct-ri') after `strftime'. + +After you are familiar with Time class, switch to test script and write assertions. + += When Modifying Another Method + +If you want to modify already-written method, setting cursor position +of corresponding test script to corresponding test method is better. +It tells rct-complete new test script and test method, so you can do +completion in the new method. diff --git a/Support/vendor/rcodetools/README.emacs b/Support/vendor/rcodetools/README.emacs index c6307c2..c3acff5 100644 --- a/Support/vendor/rcodetools/README.emacs +++ b/Support/vendor/rcodetools/README.emacs @@ -21,8 +21,19 @@ If you use icicles copy icicles-rcodetools.el too. Then require it. (require 'icicles-rcodetools) It provides wonderful `help on candidate' feature, RI document on each candidate during completion. -I'm addicted to icicles! - http://www.emacswiki.org/cgi-bin/wiki/Icicles + +If you use anything.el copy anything-rcodetools.el too. +Then require it. + (require 'anything-rcodetools) +RI document on each candidate during completion. + +anything-show-completion.el shows selection (mehod) in buffer for completion. +It is available in: + http://www.emacswiki.org/cgi-bin/wiki/download/anything-show-completion.el + +I think anything-rcodetools is more convenient than icicles-rcodetools. +I'm addicted to anything! + http://www.emacswiki.org/cgi-bin/wiki/Anything xmpfilter on buffer =================== @@ -38,8 +49,9 @@ method/class/constant completion # [EVAL IT] (describe-function 'rct-complete-symbol) -If you use icicles-rcodetools, you can browse RI document for selected candidate -by typing C-M-RET. It is wonderful icicles feature!! +If you use icicles-rcodetools or anything-rcodetools, you can browse RI document +for selected candidate by typing C-M-RET (icicles) or C-z (anything. +It is wonderful icicles and anything feature!! show RI document / jump to the definition ========================================= @@ -52,3 +64,12 @@ If use do not use this feature, evaluate: (setq rct-find-tag-if-available nil) # [EVAL IT] (describe-variable 'rct-find-tag-if-available) + +speed-up xmpfilter and completion +================================= + +# [EVAL IT] (describe-function 'rct-fork) +# [EVAL IT] (describe-function 'rct-fork-kill) + +M-x rct-fork pre-loads heavy libraries (like rails). +You need not every time wait for loading them anymore! diff --git a/Support/vendor/rcodetools/README.ja b/Support/vendor/rcodetools/README.ja new file mode 100644 index 0000000..7a32116 --- /dev/null +++ b/Support/vendor/rcodetools/README.ja @@ -0,0 +1,84 @@ + + rcodetools http://eigenclass.org/hiki.rb?rcodetools + Copyright (c) 2005-2007 Mauricio Fernandez http://eigenclass.org + Copyright (c) 2006-2008 rubikitch http://www.rubyist.net/~rubikitch/ +Use and distribution subject to the terms of the Ruby license. + += ³µÍ× +rcodetools ¤Ï Ruby ¤Î¥³¡¼¥É¤ò°·¤¦¥Ä¡¼¥ë·²¤Ç¤¹¡£ +rcodetools ¤Ë¤Ï xmpfilter ¤È¥¨¥Ç¥£¥¿¤Ë°Í¸¤·¤Ê¤¤³«È¯»Ù±ç¥Ä¡¼¥ë¤¬´Þ¤Þ¤ì¤Æ¤¤¤Þ¤¹¡£ +Emacs ¤È Vim ¤Î¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤âÍѰդ·¤Æ¤¤¤Þ¤¹¡£ + +* xmpfilter: Test::Unit assert* / RSpec should* ¼«Æ°À¸À®¡¢¥³¡¼¥ÉÃí¼á +* rct-complete: ¹âÀºÅ٥᥽¥Ã¥É̾¡¦¥¯¥é¥¹Ì¾¡¦Äê¿ô̾ÅùÊä´° +* rct-doc: ¥É¥­¥å¥á¥ó¥È»²¾È¡¦¥³¡¼¥É¥Ê¥Ó¥²¡¼¥¿¡¼ +* rct-meth-args: ¹âÀºÅ٥᥽¥Ã¥É¾ðÊó¥ê¥¹¥È¡¢TAGS ¥Õ¥¡¥¤¥ëºîÀ® +* rct-fork: Rails Åù½Å¤¤¥é¥¤¥Ö¥é¥ê¤òͽ¤á¥í¡¼¥É¤·¡¢Êä´°¤ò¹â®²½¤¹¤ë¡Ê¥µ¡¼¥Ð¡Ë +* rct-fork-client: rct-fork ¥µ¡¼¥Ð¤¬ÊÝ»ý¤¹¤ë¾õÂÖ¤«¤é Ruby ¥¹¥¯¥ê¥×¥È¤ò¼Â¹Ô¤¹¤ë +* ruby-toggle-file: ¥Æ¥¹¥È¥¹¥¯¥ê¥×¥È¤È¼ÂÁõ¥¹¥¯¥ê¥×¥È¤òÀڤ괹¤¨¤ë +* rbtest: ¾®µ¬ÌÏ¥¹¥¯¥ê¥×¥È¤Î¤¿¤á¤ÎËä¤á¹þ¤ß Test::Unit + + += »È¤¤Êý + +== ¥³¡¼¥ÉÃí¼á +¼°¤ÎÃͤòɽ¼¨¤·¤¿¤¤¹Ô¤Ë # => ¤ò²Ã¤¨¤Þ¤¹¡£ + + a, b = "foo", "baz" + a + b # => + a.size # => + +xmpfilter ¤ËÄ̤¹¤È²¼¤Î¤è¤¦¤Ë¼°¤ÎÃͤòɽ¼¨¤·¤Æ¤¯¤ì¤Þ¤¹¡£ + + a, b = "foo", "baz" + a + b # => "foobaz" + a.size # => 3 + + +== Test::Unit assert ʸÀ¸À® + +¤¹¤Ç¤Ë¤Ç¤­¤¢¤¬¤Ã¤Æ¤¤¤ë¥×¥í¥°¥é¥à¤Î¥Æ¥¹¥È¥¹¥¯¥ê¥×¥È¤ò½ñ¤¯¤Î¤ÏÌÌÅݤǤ¹¤Í¡£ + + def test_insertion + @o.insert "bar" + @o.insert "baz" + @o.size # => + @o.last # => + @o.first # => + @o.complex_computation # => + @o.last(2) # => + end + +xmpfilter¡Ê-u ¥ª¥×¥·¥ç¥ó¡Ë¤¬¼ê´Ö¤ò·Ú¸º¤·¤Æ¤¯¤ì¤Þ¤¹¡£ + + def test_insertion + @o.insert "bar" + @o.insert "baz" + assert_equal(2, @o.size) + assert_equal("baz", @o.last) + assert_equal("bar", @o.first) + assert_in_delta(3.14159265358979, @o.complex_computation, 0.0001) + assert_equal(["baz", "bar"], @o.last(2)) + end + +RSpec ¤Ë¤Ä¤¤¤Æ¤âƱÍͤΤ³¤È¤¬¤Ç¤­¤Þ¤¹¡£¡Ê-s ¥ª¥×¥·¥ç¥ó¡Ë + +== Êä´°¡¦¥É¥­¥å¥á¥ó¥È»²¾È + +ư²è¤Ë¤è¤ë¥¹¥¯¥ê¡¼¥ó¥·¥ç¥Ã¥È¤ò¸«¤Æ¤¯¤À¤µ¤¤¡£ + +http://eigenclass.org/hiki.rb?rcodetools-screenshots + +== ¾Ü¤·¤¤»È¤¤Êý +-h ¥ª¥×¥·¥ç¥ó¤ò¤Ä¤±¤ë¤È»ÈÍѲÄǽ¤Ê¥ª¥×¥·¥ç¥ó¤¬É½¼¨¤µ¤ì¤Þ¤¹¡£ + + xmpfilter -h + rct-complete -h + rct-doc -h + rct-meth-args -h + rct-fork -h + rct-fork-client -h + ruby-toggle-file -h + rbtest -h + +README.emacs ¤È README.vim ¤Ë¥¨¥Ç¥£¥¿¾å¤Ç¤Î»È¤¤Êý¤¬¾Ü¤·¤¯½ñ¤¤¤Æ¤¢¤ê¤Þ¤¹¡£ diff --git a/Support/vendor/rcodetools/README.xmpfilter b/Support/vendor/rcodetools/README.xmpfilter index 2ed67cb..1ea49dc 100644 --- a/Support/vendor/rcodetools/README.xmpfilter +++ b/Support/vendor/rcodetools/README.xmpfilter @@ -1,12 +1,14 @@ xmpfilter http://eigenclass.org/hiki.rb?xmpfilter -Copyright (c) 2005-2006 Mauricio Fernandez http://eigenclass.org +Copyright (c) 2005-2008 Mauricio Fernandez http://eigenclass.org + rubikitch Use and distribution subject to the terms of the Ruby license. Overview ======== xmpfilter is a small tool that can be used to -* generate Test::Unit assertions and RSpec expectations semi-automatically +* generate Test::Unit assertions, RSpec expectations and + expectations blocks semi-automatically * annotate source code with intermediate results (a bit like irb --simple-prompt but only for the lines explicitly marked with # =>) Very useful for example code (such as postings to ruby-talk). @@ -15,7 +17,7 @@ Usage ===== xmpfilter takes its input from stdin and writes to stdout. It can run in several modes (annotation, Test::Unit assertion expansion, RSpec expectation -generation, marker insertion); see +generation, expectations expectations generation, marker insertion); see xmpfilter -h README.emacs and README.vim describe how to use xmpfilter from your editor. @@ -34,8 +36,33 @@ README.vim) a + b # => "foobaz" a.size # => 3 -This saves much cut&pasting when you're posting to ruby-talk/ruby-core (I use -it all the time). +This saves much cut&pasting when you're posting to ruby-list/ruby-talk/ruby-core +(We use it all the time). + + +Example: multi-line code annotation +=================================== +Just add "# =>" markers to the next lines whose values you want to be shown with pp: + +a = ["1111111111111111111111111111111111111111111111111111", 123334324234242342, + 1332333333,6,8 ] +1 # => +a +# => + +will be expanded to (in one keypress in a decent editor, see README.emacs and +README.vim) + +a = ["1111111111111111111111111111111111111111111111111111", 123334324234242342, + 1332333333,6,8 ] +1 # => 1 +a +# => ["1111111111111111111111111111111111111111111111111111", +# 123334324234242342, +# 1332333333, +# 6, +# 8] + Example: assertion generation ============================= @@ -114,88 +141,146 @@ Example: RSpec expectations =========================== Here's some code before and after filtering it with xmpfilter: - class X - Y = Struct.new(:a) - def foo(b); b ? Y.new(2) : 2 end - def bar; raise "No good" end - def baz; nil end - def fubar(x); x ** 2.0 + 1 end - def babar; [1,2] end - A = 1 - A = 1 + class X + Y = Struct.new(:a) + def foo(b); b ? Y.new(2) : 2 end + def bar; raise "No good" end + def baz; nil end + def fubar(x); x ** 2.0 + 1 end + def babar; [1,2] end + A = 1 + A = 1 + end + + context "Testing xmpfilter's expectation expansion" do + setup do + @o = X.new end - context "Testing xmpfilter's expectation expansion" do - setup do - @o = X.new - end + specify "Should expand should_equal expectations" do + @o.foo(true) # => + @o.foo(true).a # => + @o.foo(false) # => + end - specify "Should expand should_equal expectations" do - @o.foo(true) # => - @o.foo(true).a # => - @o.foo(false) # => - end - - specify "Should expand should_raise expectations" do - @o.bar # => - end + specify "Should expand should_raise expectations" do + @o.bar # => + end - specify "Should expand should_be_nil expectations" do - @o.baz # => - end + specify "Should expand should_be_nil expectations" do + @o.baz # => + end - specify "Should expand correct expectations for complex values" do - @o.babar # => - end + specify "Should expand correct expectations for complex values" do + @o.babar # => + end - specify "Should expand should_be_close expectations" do - @o.fubar(10) # => - end + specify "Should expand should_be_close expectations" do + @o.fubar(10) # => end + end after piping it to xmpfilter -s: - class X - Y = Struct.new(:a) - def foo(b); b ? Y.new(2) : 2 end - def bar; raise "No good" end - def baz; nil end - def fubar(x); x ** 2.0 + 1 end - def babar; [1,2] end - A = 1 - A = 1 # !> already initialized constant A - end - - context "Testing xmpfilter's expectation expansion" do - setup do - @o = X.new - end - - specify "Should expand should_equal expectations" do - (@o.foo(true)).should_be_a_kind_of X::Y - (@o.foo(true).inspect).should_equal "#" - (@o.foo(true).a).should_equal 2 - (@o.foo(false)).should_equal 2 - end - - specify "Should expand should_raise expectations" do - lambda{(@o.bar)}.should_raise RuntimeError - end - - specify "Should expand should_be_nil expectations" do - (@o.baz).should_be_nil - end - - specify "Should expand correct expectations for complex values" do - (@o.babar).should_equal [1, 2] - end - - specify "Should expand should_be_close expectations" do - (@o.fubar(10)).should_be_close(101.0, 0.0001) - end + class X + Y = Struct.new(:a) + def foo(b); b ? Y.new(2) : 2 end + def bar; raise "No good" end + def baz; nil end + def fubar(x); x ** 2.0 + 1 end + def babar; [1,2] end + A = 1 + A = 1 # !> already initialized constant A + end + + context "Testing xmpfilter's expectation expansion" do + setup do + @o = X.new + end + + specify "Should expand should_equal expectations" do + (@o.foo(true)).should_be_a_kind_of X::Y + (@o.foo(true).inspect).should_equal "#" + (@o.foo(true).a).should_equal 2 + (@o.foo(false)).should_equal 2 + end + + specify "Should expand should_raise expectations" do + lambda{(@o.bar)}.should_raise RuntimeError + end + + specify "Should expand should_be_nil expectations" do + (@o.baz).should_be_nil + end + + specify "Should expand correct expectations for complex values" do + (@o.babar).should_equal [1, 2] + end + + specify "Should expand should_be_close expectations" do + (@o.fubar(10)).should_be_close(101.0, 0.0001) + end + end + + +Example: expectations expectations +================================== +Expectations is a light-weight unit testing framework by Jay Fields. +(http://expectations.rubyforge.org) + +Here's some code before and after filtering it with xmpfilter: + + require 'rubygems' + require 'expectations' + + S = Struct.new :a + Expectations do + 1 + 1 # => + "a".length # => + [][1] # => + 1.hoge # => + 1.1 + 1.0 # => + S.new(1) # => + end + +after piping it to xmpfilter --expectations: + + require 'rubygems' + require 'expectations' + + S = Struct.new :a + Expectations do + expect 2 do + 1 + 1 + end + + expect 1 do + "a".length + end + + expect nil do + [][1] + end + + expect NoMethodError do + 1.hoge + end + + expect 2.0999..2.1001 do + 1.1 + 1.0 end + expect S do + S.new(1) + end + + expect "#" do + S.new(1).inspect + end + + end + License ======= diff --git a/Support/vendor/rcodetools/Rakefile b/Support/vendor/rcodetools/Rakefile index 190668f..75ef377 100644 --- a/Support/vendor/rcodetools/Rakefile +++ b/Support/vendor/rcodetools/Rakefile @@ -31,50 +31,16 @@ end task :default => :test -## test data file dependency -basetestfiles = [] -copy = lambda do |t| - cp t.prerequisites.first, t.name -end - -# DO NOT EDIT!! EDITABLE -[ ["test/data/rspec_poetry-input.rb", "test/data/rspec-input.rb"], - ["test/data/unit_test_poetry-input.rb", "test/data/unit_test-input.rb"], - ["test/data/completion_emacs-input.rb", "test/data/completion-input.rb"], - ["test/data/unit_test_detect_rbtest-input.rb", "test/data/unit_test-input.rb"], - ["test/data/unit_test_detect_rbtest-output.rb", "test/data/unit_test-output.rb"], - ["test/data/unit_test_detect_rbtest2-input.rb", "test/data/unit_test_rbtest-input.rb"], - ["test/data/unit_test_detect_rbtest2-output.rb", "test/data/unit_test_rbtest-output.rb"], - ["test/data/completion_detect_rbtest-input.rb", "test/data/completion_rbtest-input.rb"], - ["test/data/completion_detect_rbtest-output.rb", "test/data/completion_rbtest-output.rb"], - ["test/data/completion_detect_rbtest2-input.rb", "test/data/completion-input.rb"], - ["test/data/completion_detect_rbtest2-output.rb", "test/data/completion-output.rb"], - ["test/data/doc_detect_rbtest-input.rb", "test/data/doc-input.rb"], - ["test/data/doc_detect_rbtest-output.rb", "test/data/doc-output.rb"], - ["test/data/doc_detect_rbtest2-input.rb", "test/data/doc_rbtest-input.rb"], - ["test/data/doc_detect_rbtest2-output.rb", "test/data/doc_rbtest-output.rb"], - -].each do |outfile, infile| - basetestfiles << outfile - file(outfile => infile, ©) -end -for test in %w[refe ri ri_emacs ri_vim] - outfile = "test/data/#{test}-input.rb" - basetestfiles << outfile - file(outfile => "test/data/doc-input.rb", ©) -end -task :base_update => basetestfiles -task :test => :base_update -task :rcov => :base_update #{{{ Package tasks PKG_FILES = FileList[ -"bin/rct-complete", "bin/rct-doc", "bin/xmpfilter", "bin/rct-meth-args", + "bin/xmpfilter", "bin/rct-*", "bin/ruby-toggle-file", "bin/rbtest", "lib/**/*.rb", -"CHANGES", "rcodetools.*", "icicles-rcodetools.el", "README", "README.*", "THANKS", +"CHANGES", "rcodetools.*", "icicles-rcodetools.el", "anything-rcodetools.el", +"README", "README.*", "THANKS", "Rakefile", "Rakefile.method_analysis", "setup.rb", -"test/**/*.rb", +"test/**/*.rb","test/**/*.taf" ] begin @@ -128,7 +94,7 @@ EOF task :gem => [:test] Rake::GemPackageTask.new(Spec) do |p| - #p.need_tar = true + p.need_tar_gz = true end rescue LoadError @@ -140,4 +106,11 @@ task :install do sh "sudo ruby setup.rb install" end +desc "release in rubyforge" +task :release => [:package] do + sh "rubyforge login" + sh "rubyforge add_release rcodetools rcodetools #{RCT_VERSION} pkg/rcodetools-#{RCT_VERSION}.0.tar.gz " + sh "rubyforge add_file rcodetools rcodetools #{RCT_VERSION} pkg/rcodetools-#{RCT_VERSION}.0.gem " +end + # vim: set sw=2 ft=ruby: diff --git a/Support/vendor/rcodetools/anything-rcodetools.el b/Support/vendor/rcodetools/anything-rcodetools.el new file mode 100644 index 0000000..e21a743 --- /dev/null +++ b/Support/vendor/rcodetools/anything-rcodetools.el @@ -0,0 +1,151 @@ +;;; anything-rcodetools.el --- accurate Ruby method completion with anything +;; $Id: anything-rcodetools.el,v 1.13 2009/04/20 16:25:37 rubikitch Exp $ + +;;; Copyright (c) 2007 rubikitch + +;; Author: rubikitch +;; URL: http://www.emacswiki.org/cgi-bin/wiki/download/anything-rcodetools.el + +;;; Use and distribution subject to the terms of the Ruby license. + +;;; Commentary: + +;; (0) You need rcodetools, anything.el and FastRI. Note that you do not have to +;; configure anything.el if you use anything.el for this package. +;; (1) You need to add to .emacs: +;; (require 'anything) +;; (require 'anything-rcodetools) +;; ;; Command to get all RI entries. +;; (setq rct-get-all-methods-command "PAGER=cat fri -l") +;; ;; See docs +;; (define-key anything-map "\C-z" 'anything-execute-persistent-action) + +;;; Commands: +;; +;; Below are complete command list: +;; +;; +;;; Customizable Options: +;; +;; Below are customizable option list: +;; + +;;; History: + +;; $Log: anything-rcodetools.el,v $ +;; Revision 1.13 2009/04/20 16:25:37 rubikitch +;; Set anything-samewindow to nil +;; +;; Revision 1.12 2009/04/18 10:12:02 rubikitch +;; Adjust to change of `use-anything-show-completion' +;; +;; Revision 1.11 2009/04/17 20:21:47 rubikitch +;; * require anything +;; * require anything-show-completion.el if available +;; +;; Revision 1.10 2009/04/17 20:11:03 rubikitch +;; removed old code +;; +;; Revision 1.9 2009/04/17 20:07:52 rubikitch +;; * use --completion-emacs-anything option +;; * New implementation of `anything-c-source-complete-ruby-all' +;; +;; Revision 1.8 2009/04/15 10:25:25 rubikitch +;; Set `anything-execute-action-at-once-if-one' t +;; +;; Revision 1.7 2009/04/15 10:24:23 rubikitch +;; regexp bug fix +;; +;; Revision 1.6 2008/01/14 17:59:34 rubikitch +;; * uniform format (anything-c-source-complete-ruby, anything-c-source-complete-ruby-all) +;; * rename command: anything-c-ri -> anything-rct-ri +;; +;; Revision 1.5 2008/01/13 17:54:04 rubikitch +;; anything-current-buffer advice. +;; +;; Revision 1.4 2008/01/08 14:47:34 rubikitch +;; Added (require 'rcodetools). +;; Revised commentary. +;; +;; Revision 1.3 2008/01/04 09:32:29 rubikitch +;; *** empty log message *** +;; +;; Revision 1.2 2008/01/04 09:21:23 rubikitch +;; fixed typo +;; +;; Revision 1.1 2008/01/04 09:21:05 rubikitch +;; Initial revision +;; + +;;; Code: + +(require 'anything) +(require 'rcodetools) +(when (require 'anything-show-completion nil t) + (use-anything-show-completion 'rct-complete-symbol--anything + '(length pattern))) + +(defun anything-rct-ri (meth) + (ri (get-text-property 0 'desc meth))) + +(defun anything-rct-complete (meth) + (save-excursion + (set-buffer anything-current-buffer) + (search-backward pattern) + (delete-char (length pattern))) + (insert meth)) + +(setq rct-complete-symbol-function 'rct-complete-symbol--anything) +(defvar anything-c-source-complete-ruby + '((name . "Ruby Method Completion") + (candidates . rct-method-completion-table) + (init + . (lambda () + (condition-case x + (rct-exec-and-eval rct-complete-command-name "--completion-emacs-anything") + ((error) (setq rct-method-completion-table nil))))) + (action + ("Completion" . anything-rct-complete) + ("RI" . anything-rct-ri)) + (volatile) + (persistent-action . anything-rct-ri))) + +(defvar rct-get-all-methods-command "PAGER=cat fri -l") +(defvar anything-c-source-complete-ruby-all + '((name . "Ruby Method Completion (ALL)") + (init + . (lambda () + (unless (anything-candidate-buffer) + (with-current-buffer (anything-candidate-buffer 'global) + (call-process-shell-command rct-get-all-methods-command nil t) + (goto-char 1) + (while (re-search-forward "^.+[:#.]\\([^:#.]+\\)$" nil t) + (replace-match "\\1\t[\\&]")))))) + (candidates-in-buffer + . (lambda () + (let ((anything-pattern (format "^%s.*%s" (regexp-quote pattern) anything-pattern))) + (anything-candidates-in-buffer)))) + (display-to-real + . (lambda (line) + (if (string-match "\t\\[\\(.+\\)\\]$" line) + (propertize (substring line 0 (match-beginning 0)) + 'desc (match-string 1 line)) + line))) + (action + ("Completion" . anything-rct-complete) + ("RI" . anything-rct-ri)) + (persistent-action . anything-rct-ri))) + + +(defun rct-complete-symbol--anything () + (interactive) + (let ((anything-execute-action-at-once-if-one t) + anything-samewindow) + (anything '(anything-c-source-complete-ruby + anything-c-source-complete-ruby-all)))) + +(provide 'anything-rcodetools) + +;; How to save (DO NOT REMOVE!!) +;; (emacswiki-post "anything-rcodetools.el") +;;; install-elisp.el ends here diff --git a/Support/vendor/rcodetools/bin/rbtest b/Support/vendor/rcodetools/bin/rbtest new file mode 100644 index 0000000..8d906cf --- /dev/null +++ b/Support/vendor/rcodetools/bin/rbtest @@ -0,0 +1,266 @@ +#! /usr/local/bin/ruby18 +# Copyright (c) 2006-2007 rubikitch +# +# Use and distribution subject to the terms of the Ruby license. + +USAGE = <<'XXX' +Usage: rbtest SCRIPT [-S RUBY_INTERPRETER] [Test::Unit OPTIONS] +Usage: rbtest [-h] [--help] [--example] + +I am rbtest, embedded Test::Unit executor for one-file scripts. +Splitting a small script into many files (executables, libraries and tests) is cumbersome. +And it is handy to put unit tests near implementations like D language, which has +built-in unittest keyword. + +Embedded Test::Unit is simpler than vanilla Test::Unit. +You do not have to define a Test::Unit::TestCase subclass, +it is automagically defined and executed by me. +Embedded Test::Unit uses =begin/=end comment blocks. + +"=begin TEST_METHOD_NAME" blocks define test methods, eg. "=begin test_foo". +"=begin rbtest" blocks define utility methods and setup/teardown methods. + +Of course, you MUST use "if __FILE__ ==$0" idiom to split executable and class/method/function. + +I am also an real-life example of rbtest usage. +Issue: + rbtest --example +to show me. + + +options: + -h, --help Print usage. + -S RUBY_INTERPRETER Use Ruby interpreter RUBY_INTERPRETER. + --example Print this file. + --output Print internally-generated test script (for debug). +XXX + + +def first_test(script_filename) + "require 'test/unit';" + + "load '#{script_filename}';" + + "class TestByRbtest < Test::Unit::TestCase;" +end + +=begin rbtest +def setup +end + +def unindent(s) + s.map{|x| x[1..-1]}.join +end +=end + +=begin test_script_to_test_script +# indent is needed to avoid syntax error. +script = < http://eigenclass.org # 2006-2007 rubikitch http://www.rubyist.net/~rubikitch/ @@ -6,6 +6,7 @@ # Use and distribution subject to the same conditions as Ruby. require 'rcodetools/options' +include Rcodetools $VERBOSE = nil $__method_args_off = true @@ -22,6 +23,7 @@ rct-meth-args [-Idirectory] [-i] [-m] [-c] [-n] [ ...] -n print the filename and line number with output lines -t generate TAGS output +--summarize summary output sorted by method name The given files will be #require()d in order. Examples: @@ -29,7 +31,7 @@ Examples: rct-meth-args thread rct-meth-args -c rubygems EOF - exit + exit # ' end def debugprint(*args) @@ -98,6 +100,33 @@ module MethodArgs end end + class SummarizePrinter + def initialize + @hash = Hash.new + at_exit { print_result } + end + + def method_info(io, x) + @io = io + prefix = x[:location] ? "#{x[:location].filename}:#{x[:location].lineno}:" : "" + (@hash[x[:meth]]||=[]) << "#{prefix}#{x[:fullname]}#{x[:arg_desc]}" unless x[:klass].to_s == "" + end + + def included_location(io, x) + # not implemented + end + + def print_result + @hash.keys.sort.each do |meth| + @io.puts meth + @hash[meth].each do |line| + @io.puts line + end + @io.puts + end + end + end + class TagsPrinter def initialize @previous_filename = "" @@ -129,6 +158,7 @@ module MethodArgs arg_desc = " " + arg_desc unless arg_desc.empty? flag = is_singleton ? "." : "#" x = { :arg_desc => arg_desc, :klass => klass, + :meth => meth.to_s, :fullname => [klass, flag, meth].join, :location => with_location && location, } @@ -255,6 +285,7 @@ ARGV.each do |arg| case arg when "-n"; $__with_location = true when "-t"; $__printer = TagsPrinter.new; $__with_location = true + when "--summarize"; $__printer = SummarizePrinter.new when /-I(.+)$/; $:.unshift $1 when "-I"; i_opt_p = true when "--dev"; OptionHandler.auto_include_paths($:, Dir.pwd) diff --git a/Support/vendor/rcodetools/bin/ruby-toggle-file b/Support/vendor/rcodetools/bin/ruby-toggle-file new file mode 100644 index 0000000..9adccc9 --- /dev/null +++ b/Support/vendor/rcodetools/bin/ruby-toggle-file @@ -0,0 +1,26 @@ +#! /usr/local/bin/ruby18 +require 'ruby_toggle_file' +require 'optparse' + +USAGE = < markers.") do klass = XMPAddMarkers end @@ -71,5 +76,10 @@ end targetcode = ARGF.read Dir.chdir options[:wd] if options[:wd] +if XMPFilter.detect_rbtest(targetcode, options) + require 'rcodetools/xmptestunitfilter' + klass = XMPTestUnitFilter +end + # Do the job. dispatched by klass. puts klass.run(targetcode, options) diff --git a/Support/vendor/rcodetools/lib/rcodetools/compat.rb b/Support/vendor/rcodetools/lib/rcodetools/compat.rb new file mode 100644 index 0000000..13e5083 --- /dev/null +++ b/Support/vendor/rcodetools/lib/rcodetools/compat.rb @@ -0,0 +1,14 @@ +if RUBY_VERSION >= "1.9" + class String + alias :each :each_line + include Enumerable + end + + module Enumerable + alias :enum_with_index :each_with_index + end + + class Array + alias :to_s :join + end +end diff --git a/Support/vendor/rcodetools/lib/rcodetools/completion.rb b/Support/vendor/rcodetools/lib/rcodetools/completion.rb index 4ea1320..ccc936a 100644 --- a/Support/vendor/rcodetools/lib/rcodetools/completion.rb +++ b/Support/vendor/rcodetools/lib/rcodetools/completion.rb @@ -3,6 +3,9 @@ require 'rcodetools/xmpfilter' require 'enumerator' + +module Rcodetools + # Common routines for XMPCompletionFilter/XMPDocFilter module ProcessParticularLine def fill_literal!(expr) @@ -78,8 +81,8 @@ def _handle_keywords(expr_orig, column) def aref_or_aset?(right_stripped, last_char) if last_char == ?[ case right_stripped - when /\]\s*=/: "[]=" - when /\]/: "[]" + when /\]\s*=/ then "[]=" + when /\]/ then "[]" end end end @@ -156,7 +159,7 @@ def runtime_data_with_class(code, lineno, column=nil) debugprint "newcode", newcode.gsub(/;/, "\n"), "-"*80 stdout, stderr = execute(newcode) output = stderr.readlines - debugprint "stdout", output, "-"*80 + debugprint "stderr", output, "-"*80 output = output.reject{|x| /^-:[0-9]+: warning/.match(x)} runtime_data = extract_data(output) if exception = /^-:[0-9]+:.*/m.match(output.join) @@ -164,6 +167,7 @@ def runtime_data_with_class(code, lineno, column=nil) end begin dat = runtime_data.results[1][0] + debugprint "dat = #{dat.inspect}" [dat[0], dat[1..-1].to_s] rescue raise RuntimeDataError, runtime_data.inspect @@ -178,7 +182,7 @@ def __magic_help_code(result, v, meth) code = <<-EOC #{result} = #{v}.method(#{meth}).inspect.match( %r[\\A#<(?:Unbound)?Method: (.*?)>\\Z] )[1].sub(/\\A.*?\\((.*?)\\)(.*)\\Z/){ "\#{$1}\#{$2}" }.sub(/##/) { "\#{$1}." } #{result} = #{v}.to_s + ".new" if #{result} == 'Class#new' and #{v}.private_method_defined?(:initialize) - #{result} = "Object#" + #{meth} if #{result} =~ /^Kernel#/ and Kernel.instance_methods(false).include? #{meth} + #{result} = "Object#" + #{meth} if #{result} =~ /^Kernel#/ and Kernel.instance_methods(false).map{|x| x.to_s}.include? #{meth} #{result} EOC end @@ -208,7 +212,9 @@ def magic_help_code(recv, meth) def methods_map_code(recv) # delimiter is \0 - %Q[map{|m| "\#{m}\\0" + #{magic_help_code((recv), 'm')}}] + m = "#{VAR}_m" + mhc = magic_help_code((recv), m) + %Q[map{|%s| "\#{%s}\\0" + %s}] % [m, m, mhc] end def split_method_info(minfo) @@ -219,11 +225,11 @@ def prepare_line(expr, column) set_expr_and_postfix!(expr, column){|c| /^.{#{c}}/ } @prefix = expr case expr - when /^\$\w+$/ # global variable + when /^\$\w*$/ # global variable __prepare_line 'nil', 'global_variables', '%n' - when /^@@\w+$/ # class variable + when /^@@\w*$/ # class variable __prepare_line 'nil', 'Module === self ? class_variables : self.class.class_variables', '%n' - when /^@\w+$/ # instance variable + when /^@\w*$/ # instance variable __prepare_line 'nil', 'instance_variables', '%n' when /^([A-Z].*)::([^.]*)$/ # nested constants / class methods @prefix = $2 @@ -231,7 +237,7 @@ def prepare_line(expr, column) %Q[#$1.constants + #$1.methods(true).#{methods_map_code($1)}] when /^[A-Z]\w*$/ # normal constants __prepare_line 'nil', 'Module.constants', '%n' - when /^(.*::.+)\.(.+)$/ # toplevel class methods + when /^(.*::.+)\.(.*)$/ # toplevel class methods @prefix = $2 __prepare_line $1, "#$1.methods", %Q[%n.#{methods_map_code($1)}] @@ -270,22 +276,28 @@ def ___prepare_line(recv, all_completion_expr) idx = 1 oneline_ize(< " + #{rcv}.to_s + " " + #{v}.join(" ")) || #{v} exit EOC end + def candidates_with_class(code, lineno, column=nil) + klass, methods = runtime_data_with_class(code, lineno, column) rescue ["", ""] + raise NoCandidates, "No candidates." if methods.nil? or methods.empty? + [klass, methods.split(/ /).sort] + end + # Array of completion candidates. + class NoCandidates < RuntimeError; end def candidates(code, lineno, column=nil) - methods = runtime_data(code, lineno, column) rescue "" - methods.split(/ /).sort + candidates_with_class(code, lineno, column)[1] end # Completion code for editors. def completion_code(code, lineno, column=nil) - candidates(code, lineno, column).join("\n") + candidates(code, lineno, column).join("\n") rescue "\n" end end @@ -299,6 +311,8 @@ class XMPCompletionClassInfoFilter < XMPCompletionFilter def completion_code(code, lineno, column=nil) candidates(code, lineno, column).join("\n").tr("\0", "\t") + rescue NoCandidates + "" end end @@ -318,23 +332,27 @@ def completion_code(code, lineno, column=nil) table << "))\n" alist << "))\n" rescue Exception => err - return %Q[(error "#{err.message}")] + return error_code(err) end elisp << table << alist elisp << %Q[(setq pattern "#{prefix}")\n] elisp << %Q[(try-completion pattern rct-method-completion-table nil)\n] elisp << ")" # /progn end -end -class XMPCompletionEmacsIciclesFilter < XMPCompletionFilter - @candidates_with_description_flag = true + def error_code(err) + case err + when NoCandidates + %Q[(error "#{err.message}")] + else + %Q[(error "#{err.message}\n#{err.backtrace.join("\n")}")] + end - def candidates(code, lineno, column=nil) - klass, methods = runtime_data_with_class(code, lineno, column) rescue ["", ""] - @klass = klass - methods.split(/ /).sort end +end + +class XMPCompletionEmacsIciclesFilter < XMPCompletionEmacsFilter + @candidates_with_description_flag = true def completion_code(code, lineno, column=nil) elisp = "(progn\n" @@ -342,7 +360,8 @@ def completion_code(code, lineno, column=nil) help_alist = "(setq alist '(" begin - candidates(code, lineno, column).sort.each do |minfo| + klass, cands = candidates_with_class(code, lineno, column) + cands.sort.each do |minfo| meth, description = split_method_info(minfo) table << format('("%s\\t[%s]") ', meth, description) help_alist << format('("%s" . "%s")', meth, description) @@ -350,12 +369,38 @@ def completion_code(code, lineno, column=nil) table << "))\n" help_alist << "))\n" rescue Exception => err - return %Q[(error "#{err.message}")] + return error_code(err) end elisp << table << help_alist elisp << %Q[(setq pattern "#{prefix}")\n] - elisp << %Q[(setq klass "#{@klass}")\n] + elisp << %Q[(setq klass "#{klass}")\n] + elisp << ")" # /progn + end +end + +class XMPCompletionEmacsAnythingFilter < XMPCompletionEmacsFilter + @candidates_with_description_flag = true + + def completion_code(code, lineno, column=nil) + elisp = "(progn\n" + table = "(setq rct-method-completion-table `(" + + begin + klass, cands = candidates_with_class(code, lineno, column) + cands.sort.each do |minfo| + meth, description = split_method_info(minfo) + table << format('("%s\\t[%s]" . ,(propertize "%s" \'desc "%s")) ', + meth, description, meth, description) + end + table << "))\n" + rescue Exception => err + return error_code(err) + end + elisp << table + elisp << %Q[(setq pattern "#{prefix}")\n] + elisp << %Q[(setq klass "#{klass}")\n] elisp << ")" # /progn end end +end diff --git a/Support/vendor/rcodetools/lib/rcodetools/doc.rb b/Support/vendor/rcodetools/lib/rcodetools/doc.rb index 30c3274..9a3e752 100644 --- a/Support/vendor/rcodetools/lib/rcodetools/doc.rb +++ b/Support/vendor/rcodetools/lib/rcodetools/doc.rb @@ -1,6 +1,8 @@ require 'rcodetools/completion' # Call Ri for any editors!! # by rubikitch +module Rcodetools + class XMPDocFilter < XMPFilter include ProcessParticularLine @@ -163,3 +165,4 @@ def doc(code, lineno, column=nil) end end +end diff --git a/Support/vendor/rcodetools/lib/rcodetools/fork.rb b/Support/vendor/rcodetools/lib/rcodetools/fork.rb new file mode 100644 index 0000000..ccf1c86 --- /dev/null +++ b/Support/vendor/rcodetools/lib/rcodetools/fork.rb @@ -0,0 +1,229 @@ +## Rcodetools version of ruby_fork +# +# Based on ruby_fork.rb by Ryan Davis, Eric Hodel, Zen Spider Software +# +# (The MIT License) +# +# Copyright (c) 2006 Ryan Davis, Eric Hodel, Zen Spider Software +# 2007 rubikitch +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +require 'optparse' +require 'socket' +require 'rcodetools/fork_config' + +module Rcodetools +module Fork + + USAGE_HELP = < [], + :code => [], + :extra_paths => [], + :port => PORT, + } + + def self.add_env_args(opts, settings) + opts.separator '' + opts.separator 'Process environment options:' + + opts.separator '' + opts.on('-e CODE', 'Execute CODE in parent process.', + 'May be specified multiple times.') do |code| + settings[:code] << code + end + + opts.separator '' + opts.on('-I DIRECTORY', 'Adds DIRECTORY to $LOAD_PATH.', + 'May be specified multiple times.') do |dir| + settings[:extra_paths] << dir + end + + opts.separator '' + opts.on('-r LIBRARY', 'Require LIBRARY in the parent process.', + 'May be specified multiple times.') do |lib| + settings[:requires] << lib + end + end + + def self.daemonize(io = File.open('/dev/null', 'r+')) + fork and exit! + Process.setsid + fork and exit! + + STDIN.reopen io + STDOUT.reopen io + STDERR.reopen io + + yield if block_given? + end + + def self.parse_client_args(args) + settings = Marshal.load Marshal.dump(DEFAULT_SETTINGS) + + opts = OptionParser.new do |opts| + opts.banner = "Usage: #{$0} [options]\n#{USAGE_HELP}" + + opts.separator '' + opts.on('-p', '--port PORT', + 'Listen for connections on PORT.', + "Default: #{settings[:port]}") do |port| + settings[:port] = port.to_i + end + + opts.separator '' + opts.on('-h', '--help', 'You\'re looking at it.') do + $stderr.puts opts + exit 1 + end + + add_env_args opts, settings + end + + opts.parse! args + + return settings + end + + def self.parse_server_args(args) + settings = Marshal.load Marshal.dump(DEFAULT_SETTINGS) + + opts = OptionParser.new do |opts| + opts.banner = "Usage: #{$0} [options]\n#{USAGE_HELP}" + + opts.separator '' + opts.on('-p', '--port PORT', + 'Listen for connections on PORT.', + "Default: #{settings[:port]}") do |port| + settings[:port] = port.to_i + end + + opts.separator '' + opts.on('-h', '--help', 'You\'re looking at it.') do + $stderr.puts opts + exit 1 + end + + add_env_args opts, settings + end + + opts.parse! args + + return settings + end + + def self.start_client(args = ARGV) + trap 'INT' do exit 1 end # Exit gracefully + + settings = parse_client_args args + + args = Marshal.dump [settings, ARGV] + + socket = TCPSocket.new 'localhost', settings[:port] + + socket.puts args.length + socket.write args + socket.close_write + + until socket.eof? + $stdout.puts socket.gets + end + end + + def self.start_server(args = ARGV) + begin + require 'rubygems' + rescue LoadError + end + write_pwd + settings = parse_server_args args + setup_environment settings + + server = TCPServer.new 'localhost', settings[:port] + + $stderr.puts "#{$0} Running as PID #{$$} on #{settings[:port]}" + + loop do + Thread.new server.accept do |socket| + begin + args_length = socket.gets.to_i + args = socket.read args_length + settings, argv = Marshal.load args + + fork do + daemonize socket do + ARGV.replace argv + setup_environment settings + socket.close + end + end + + socket.close # close my copy. + rescue => e + socket.close if socket + end + end + end + rescue Interrupt, SystemExit + File.unlink PWD_FILE + rescue Exception => e + File.unlink PWD_FILE + puts "Failed to catch #{e.class}:#{e.message}" + puts "\t#{e.backtrace.join "\n\t"}" + end + + def self.setup_environment(settings) + settings[:extra_paths].map! { |dir| dir.split ':' } + settings[:extra_paths].flatten! + settings[:extra_paths].each { |dir| $:.unshift dir } + + begin + settings[:requires].each { |file| require file } + settings[:code].each { |code| eval code, TOPLEVEL_BINDING } + rescue Exception + $@.reject! {|s| s =~ %r!rcodetools/fork\.rb!} + raise + end + end + +end + +end diff --git a/Support/vendor/rcodetools/lib/rcodetools/fork_config.rb b/Support/vendor/rcodetools/lib/rcodetools/fork_config.rb new file mode 100644 index 0000000..e22b4cd --- /dev/null +++ b/Support/vendor/rcodetools/lib/rcodetools/fork_config.rb @@ -0,0 +1,26 @@ + +module Rcodetools + +module Fork + PORT = 9085 + # Contains $PWD of rct-fork server. Exists only while running. + PWD_FILE = File.expand_path "~/.rct-fork.pwd" + + def self.chdir_fork_directory + if run? + Dir.chdir File.read(PWD_FILE) + else + raise "rct-fork is not running." + end + end + + def self.write_pwd + open(PWD_FILE, "w"){|f| f.print Dir.pwd } + end + + def self.run? + File.file? PWD_FILE + end +end + +end diff --git a/Support/vendor/rcodetools/lib/rcodetools/options.rb b/Support/vendor/rcodetools/lib/rcodetools/options.rb index ccf19a3..8ba9209 100644 --- a/Support/vendor/rcodetools/lib/rcodetools/options.rb +++ b/Support/vendor/rcodetools/lib/rcodetools/options.rb @@ -1,5 +1,6 @@ require 'optparse' +module Rcodetools # Domain specific OptionParser extensions module OptionHandler def set_banner @@ -12,9 +13,18 @@ def handle_position(options) on("--line=LINE", "Current line number.") do |n| options[:lineno] = n.to_i end - on("--column=COLUMN", "Current column number.") do |n| + on("--column=COLUMN", "Current column number in BYTE.") do |n| options[:column] = n.to_i end + on("-t TEST", "--test=TEST", + "Execute test script. ", + "TEST is TESTSCRIPT, TESTSCRIPT@TESTMETHOD, or TESTSCRIPT@LINENO.", + "You must specify --filename option.") do |t| + options[:test_script], options[:test_method] = t.split(/@/) + end + on("--filename=FILENAME", "Filename of standard input.") do |f| + options[:filename] = f + end end def handle_interpreter(options) @@ -36,7 +46,15 @@ def handle_interpreter(options) on("-e EXPR", "--eval=EXPR", "--stub=EXPR", "Evaluate EXPR after execution.") do |expr| options[:evals] << expr end - + on("--fork", "Use rct-fork-client if rct-fork is running.") do + options[:detect_rct_fork] = true + end + on("--rbtest", "Use rbtest.") do + options[:use_rbtest] = true + end + on("--detect-rbtest", "Use rbtest if '=begin test_*' blocks exist.") do + options[:detect_rbtest] = true + end end def handle_misc(options) @@ -48,6 +66,12 @@ def handle_misc(options) on("--debug", "Write transformed source code to xmp-tmp.PID.rb.") do options[:dump] = "xmp-tmp.#{Process.pid}.rb" end + on("--tmpfile", "--tempfile", "Use tmpfile instead of open3. (non-windows)") do + options[:execute_ruby_tmpfile] = true + end + on("-w N", "--width N", Integer, "Set width of multi-line annotation. (xmpfilter only)") do |width| + options[:width] = width + end separator "" on("-h", "--help", "Show this message") do puts self @@ -79,10 +103,20 @@ def set_extra_opts(options) end end +def check_opts(options) + if options[:test_script] + unless options[:filename] + $stderr.puts "You must specify --filename as well as -t(--test)." + exit 1 + end + end +end + DEFAULT_OPTIONS = { :interpreter => "ruby", :options => ["hoge"], :min_codeline_size => 50, + :width => 79, :libs => [], :evals => [], :include_paths => [], @@ -92,4 +126,11 @@ def set_extra_opts(options) :use_parentheses => true, :column => nil, :output_stdout => true, + :test_script => nil, + :test_method => nil, + :detect_rct_fork => false, + :use_rbtest => false, + :detect_rbtest => false, + :execute_ruby_tmpfile => false, } +end # /Rcodetools diff --git a/Support/vendor/rcodetools/lib/rcodetools/xmpfilter.rb b/Support/vendor/rcodetools/lib/rcodetools/xmpfilter.rb old mode 100644 new mode 100755 index 2cd0368..a82854d --- a/Support/vendor/rcodetools/lib/rcodetools/xmpfilter.rb +++ b/Support/vendor/rcodetools/lib/rcodetools/xmpfilter.rb @@ -1,10 +1,21 @@ #!/usr/bin/env ruby -# Copyright (c) 2005-2007 Mauricio Fernandez http://eigenclass.org +# Copyright (c) 2005-2008 Mauricio Fernandez http://eigenclass.org # rubikitch # Use and distribution subject to the terms of the Ruby license. +# This is needed regexps cannot match with invalid-encoding strings. +# xmpfilter is unaware of script encoding. +Encoding.default_external = "ASCII-8BIT" if RUBY_VERSION >= "1.9" + +ENV['HOME'] ||= "#{ENV['HOMEDRIVE']}#{ENV['HOMEPATH']}" +require 'rcodetools/fork_config' +require 'rcodetools/compat' +require 'tmpdir' + +module Rcodetools + class XMPFilter - VERSION = "0.5.0" + VERSION = "0.8.5" MARKER = "!XMP#{Time.new.to_i}_#{Process.pid}_#{rand(1000000)}!" XMP_RE = Regexp.new("^" + Regexp.escape(MARKER) + '\[([0-9]+)\] (=>|~>|==>) (.*)') @@ -17,6 +28,23 @@ class XMPFilter :include_paths => [], :warnings => true, :use_parentheses => true} + def windows? + /win|mingw/ =~ RUBY_PLATFORM && /darwin/ !~ RUBY_PLATFORM + end + + Interpreter = Struct.new(:options, :execute_method, :accept_debug, :accept_include_paths, :chdir_proc) + INTERPRETER_RUBY = Interpreter.new(["-w"], + :execute_ruby, true, true, nil) + INTERPRETER_RBTEST = Interpreter.new(["-S", "rbtest"], + :execute_script, false, false, nil) + INTERPRETER_FORK = Interpreter.new(["-S", "rct-fork-client"], + :execute_tmpfile, false, true, + lambda { Fork::chdir_fork_directory }) + + def self.detect_rbtest(code, opts) + opts[:use_rbtest] ||= (opts[:detect_rbtest] and code =~ /^=begin test./) ? true : false + end + # The processor (overridable) def self.run(code, opts) new(opts).annotate(code) @@ -24,6 +52,7 @@ def self.run(code, opts) def initialize(opts = {}) options = INITIALIZE_OPTS.merge opts + @interpreter_info = INTERPRETER_RUBY @interpreter = options[:interpreter] @options = options[:options] @libs = options[:libs] @@ -34,8 +63,55 @@ def initialize(opts = {}) @warnings = options[:warnings] @parentheses = options[:use_parentheses] @ignore_NoMethodError = options[:ignore_NoMethodError] - + test_script = options[:test_script] + test_method = options[:test_method] + filename = options[:filename] + @execute_ruby_tmpfile = options[:execute_ruby_tmpfile] @postfix = "" + @stdin_path = nil + @width = options[:width] + + initialize_rct_fork if options[:detect_rct_fork] + initialize_rbtest if options[:use_rbtest] + initialize_for_test_script test_script, test_method, filename if test_script and !options[:use_rbtest] + end + + def initialize_rct_fork + if Fork::run? + @interpreter_info = INTERPRETER_FORK + end + end + + def initialize_rbtest + @interpreter_info = INTERPRETER_RBTEST + end + + def initialize_for_test_script(test_script, test_method, filename) + test_script.replace File.expand_path(test_script) + filename.replace File.expand_path(filename) + unless test_script == filename + basedir = common_path(test_script, filename) + relative_filename = filename[basedir.length+1 .. -1].sub(%r!^lib/!, '') + @evals << %Q!$LOADED_FEATURES << #{relative_filename.dump}! + @evals << safe_require_code('test/unit') + @evals << %Q!load #{test_script.dump}! + end + test_method = get_test_method_from_lineno(test_script, test_method.to_i) if test_method =~ /^\d/ + @evals << %Q!Test::Unit::AutoRunner.run(false, nil, ["-n", #{test_method.dump}])! if test_method + end + + def get_test_method_from_lineno(filename, lineno) + lines = File.readlines(filename) + (lineno-1).downto(0) do |i| + if lines[i] =~ /^ *def *(test_[A-Za-z0-9?!_]+)$/ + return $1 + end + end + nil + end + + def common_path(a, b) + (a.split(File::Separator) & b.split(File::Separator)).join(File::Separator) end def add_markers(code, min_codeline_size = 50) @@ -49,24 +125,31 @@ def add_markers(code, min_codeline_size = 50) ret end + SINGLE_LINE_RE = /^(?!(?:\s+|(?:\s*#.+)?)# ?=>)(.*) # ?=>.*/ + MULTI_LINE_RE = /^(.*)\n(( *)# ?=>.*(?:\n|\z))(?: *# .*\n)*/ def annotate(code) idx = 0 - newcode = code.gsub(/^(.*) # =>.*/){|l| prepare_line($1, idx += 1) } - if @dump - File.open(@dump, "w"){|f| f.puts newcode} - end + code = code.gsub(/ # !>.*/, '') + newcode = code.gsub(SINGLE_LINE_RE){ prepare_line($1, idx += 1) } + newcode.gsub!(MULTI_LINE_RE){ prepare_line($1, idx += 1, true)} + File.open(@dump, "w"){|f| f.puts newcode} if @dump stdout, stderr = execute(newcode) output = stderr.readlines runtime_data = extract_data(output) idx = 0 - annotated = code.gsub(/^(.*) # =>.*/) do |l| + annotated = code.gsub(SINGLE_LINE_RE) { |l| expr = $1 if /^\s*#/ =~ l l else annotated_line(l, expr, runtime_data, idx += 1) end - end.gsub(/ # !>.*/, '').gsub(/# (>>|~>)[^\n]*\n/m, ""); + } + annotated.gsub!(/ # !>.*/, '') + annotated.gsub!(/# (>>|~>)[^\n]*\n/m, ""); + annotated.gsub!(MULTI_LINE_RE) { |l| + annotated_multi_line(l, $1, $3, runtime_data, idx += 1) + } ret = final_decoration(annotated, output) if @output_stdout and (s = stdout.read) != "" ret << s.inject(""){|s,line| s + "# >> #{line}".chomp + "\n" } @@ -78,17 +161,28 @@ def annotated_line(line, expression, runtime_data, idx) "#{expression} # => " + (runtime_data.results[idx].map{|x| x[1]} || []).join(", ") end - def prepare_line_annotation(expr, idx) + def annotated_multi_line(line, expression, indent, runtime_data, idx) + pretty = (runtime_data.results[idx].map{|x| x[1]} || []).join(", ") + first, *rest = pretty.to_a + rest.inject("#{expression}\n#{indent}# => #{first || "\n"}") {|s, l| s << "#{indent}# " << l } + end + + def prepare_line_annotation(expr, idx, multi_line=false) v = "#{VAR}" blocal = "__#{VAR}" blocal2 = "___#{VAR}" - # rubikitch: oneline-ized -# < " + #{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})) -# EOF + lastmatch = "____#{VAR}" + if multi_line + pp = safe_require_code "pp" + result = "((begin; #{lastmatch} = $~; PP.pp(#{v}, '', #{@width-5}).gsub(/\\r?\\n/, 'PPPROTECT'); ensure; $~ = #{lastmatch} end))" + else + pp = '' + result = "#{v}.inspect" + end oneline_ize(<<-EOF).chomp +#{pp} #{v} = (#{expr}) -$stderr.puts("#{MARKER}[#{idx}] => " + #{v}.class.to_s + " " + #{v}.inspect) || begin +$stderr.puts("#{MARKER}[#{idx}] => " + #{v}.class.to_s + " " + #{result}) || begin $stderr.puts local_variables local_variables.each{|#{blocal}| #{blocal2} = eval(#{blocal}) @@ -107,24 +201,46 @@ def prepare_line_annotation(expr, idx) end alias_method :prepare_line, :prepare_line_annotation + def safe_require_code(lib) + oldverbose = "$#{VAR}_old_verbose" + "#{oldverbose} = $VERBOSE; $VERBOSE = false; require '#{lib}'; $VERBOSE = #{oldverbose}" + end + private :safe_require_code + + def execute_ruby(code) + meth = (windows? or @execute_ruby_tmpfile) ? :execute_tmpfile : :execute_popen + __send__ meth, code + end + def execute_tmpfile(code) + ios = %w[_ stdin stdout stderr] stdin, stdout, stderr = (1..3).map do |i| - fname = "xmpfilter.tmpfile_#{Process.pid}-#{i}.rb" + fname = if $DEBUG + "xmpfilter.tmpfile_#{ios[i]}.rb" + else + "xmpfilter.tmpfile_#{Process.pid}-#{i}.rb" + end f = File.open(fname, "w+") - at_exit { f.close unless f.closed?; File.unlink fname } + at_exit { f.close unless f.closed?; File.unlink fname unless $DEBUG} f end stdin.puts code stdin.close + @stdin_path = File.expand_path stdin.path exe_line = <<-EOF.map{|l| l.strip}.join(";") - $stdout.reopen('#{stdout.path}', 'w') - $stderr.reopen('#{stderr.path}', 'w') - $0.replace '#{stdin.path}' + $stdout.reopen('#{File.expand_path(stdout.path)}', 'w') + $stderr.reopen('#{File.expand_path(stderr.path)}', 'w') + $0 = '#{File.expand_path(stdin.path)}' ARGV.replace(#{@options.inspect}) - load #{stdin.path.inspect} + load #{File.expand_path(stdin.path).inspect} #{@evals.join(";")} EOF + debugprint "execute command = #{(interpreter_command << "-e" << exe_line).join ' '}" + + oldpwd = Dir.pwd + @interpreter_info.chdir_proc and @interpreter_info.chdir_proc.call system(*(interpreter_command << "-e" << exe_line)) + Dir.chdir oldpwd [stdout, stderr] end @@ -137,16 +253,36 @@ def execute_popen(code) [stdout, stderr] end - if /win|mingw/ =~ RUBY_PLATFORM && /darwin/ !~ RUBY_PLATFORM - alias_method :execute, :execute_tmpfile - else - alias_method :execute, :execute_popen + def execute_script(code) + path = File.expand_path("xmpfilter.tmpfile_#{Process.pid}.rb", Dir.tmpdir) + File.open(path, "w"){|f| f.puts code} + at_exit { File.unlink path if File.exist? path} + stdout_path, stderr_path = (1..2).map do |i| + fname = "xmpfilter.tmpfile_#{Process.pid}-#{i}.rb" + File.expand_path(fname, Dir.tmpdir) + end + args = *(interpreter_command << %["#{path}"] << "2>" << + %["#{stderr_path}"] << ">" << %["#{stdout_path}"]) + system(args.join(" ")) + + [stdout_path, stderr_path].map do |fullname| + f = File.open(fullname, "r") + at_exit { + f.close unless f.closed? + File.unlink fullname if File.exist? fullname + } + f + end + end + + def execute(code) + __send__ @interpreter_info.execute_method, code end def interpreter_command - r = [@interpreter, "-wKu"] - r << "-d" if $DEBUG - r << "-I#{@include_paths.join(":")}" unless @include_paths.empty? + r = [ @interpreter ] + @interpreter_info.options + r << "-d" if $DEBUG and @interpreter_info.accept_debug + r << "-I#{@include_paths.join(":")}" if @interpreter_info.accept_include_paths and !@include_paths.empty? @libs.each{|x| r << "-r#{x}" } unless @libs.empty? (r << "-").concat @options unless @options.empty? r @@ -161,7 +297,7 @@ def extract_data(output) case op when "=>" klass, value = /(\S+)\s+(.*)/.match(result).captures - results[result_id.to_i] << [klass, value] + results[result_id.to_i] << [klass, value.gsub(/PPPROTECT/, "\n")] when "~>" exceptions[result_id.to_i] << result when "==>" @@ -187,14 +323,16 @@ def final_decoration(code, output) end end output = output.reject{|x| /^-:[0-9]+: warning/.match(x)} - if exception = /^-:[0-9]+:.*/m.match(output.join) - ret << exception[0].map{|line| "# ~> " + line } + if exception = /^-e?:[0-9]+:.*|^(?!!XMP)[^\n]+:[0-9]+:in .*/m.match(output.join) + err = exception[0] + err.gsub!(Regexp.union(@stdin_path), '-') if @stdin_path + ret << err.map{|line| "# ~> " + line } end ret end def oneline_ize(code) - "((" + code.gsub(/\r?\n|\r/, ';') + "))#{@postfix}\n" + "((" + code.gsub(/\r?\n|\r/, ';') + "));#{@postfix}\n" end def debugprint(*args) @@ -207,3 +345,5 @@ def self.run(code, opts) new(opts).add_markers(code, opts[:min_codeline_size]) end end + +end diff --git a/Support/vendor/rcodetools/lib/rcodetools/xmptestunitfilter.rb b/Support/vendor/rcodetools/lib/rcodetools/xmptestunitfilter.rb index e89354b..e792d65 100644 --- a/Support/vendor/rcodetools/lib/rcodetools/xmptestunitfilter.rb +++ b/Support/vendor/rcodetools/lib/rcodetools/xmptestunitfilter.rb @@ -1,10 +1,14 @@ require 'rcodetools/xmpfilter' + +module Rcodetools + +FLOAT_TOLERANCE = 0.0001 class XMPTestUnitFilter < XMPFilter def initialize(opts = {}) super @output_stdout = false mod = @parentheses ? :WithParentheses : :Poetry - extend self.class.const_get(mod) + extend self.class.const_get(mod) unless opts[:_no_extend_module] end private @@ -70,7 +74,7 @@ def nil_assertion(expression) def value_assertions(klass_txt, value_txt, value, expression) case value when Float - ["assert_in_delta(#{value.inspect}, #{expression}, 0.0001)"] + ["assert_in_delta(#{value.inspect}, #{expression}, #{FLOAT_TOLERANCE})"] when Numeric, String, Hash, Array, Regexp, TrueClass, FalseClass, Symbol, NilClass ["assert_equal(#{value_txt}, #{expression})"] else @@ -96,7 +100,7 @@ def nil_assertion(expression) def value_assertions(klass_txt, value_txt, value, expression) case value when Float - ["assert_in_delta #{value.inspect}, #{expression}, 0.0001"] + ["assert_in_delta #{value.inspect}, #{expression}, #{FLOAT_TOLERANCE}"] when Numeric, String, Hash, Array, Regexp, TrueClass, FalseClass, Symbol, NilClass ["assert_equal #{value_txt}, #{expression}"] else @@ -116,82 +120,194 @@ def equal_assertion(expected, actual) end class XMPRSpecFilter < XMPTestUnitFilter + def initialize(x={}) + super(x.merge(:_no_extend_module => true)) + load_rspec + specver = (Spec::VERSION::STRING rescue "1.0.0") + api_module = specver >= "0.8.0" ? NewAPI : OldAPI + mod = @parentheses ? :WithParentheses : :Poetry + extend api_module.const_get(mod) + extend api_module + end + private - def execute(code) - codefile = "xmpfilter.rspec_tmpfile_#{Process.pid}.rb" - File.open(codefile, "w"){|f| f.puts code} - path = File.expand_path(codefile) - at_exit { File.unlink path if File.exist? path} - stdout, stderr = (1..2).map do |i| - fname = "xmpfilter.rspec_tmpfile_#{Process.pid}-#{i}.rb" - fullname = File.expand_path(fname) - at_exit { File.unlink fullname if File.exist? fullname} - File.open(fname, "w+") - end - args = *(interpreter_command << %["#{codefile}"] << "2>" << - %["#{stderr.path}"] << ">" << %["#{stdout.path}"]) - system(args.join(" ")) - [stdout, stderr] + def load_rspec + begin + require 'spec/version' + rescue LoadError + require 'rubygems' + begin + require 'spec/version' + rescue LoadError # if rspec isn't available, use most recent conventions + end + end end + alias :execute :execute_script + def interpreter_command [@interpreter] + @libs.map{|x| "-r#{x}"} end - def raise_assertion(expression, exceptions, index) - ["lambda{#{expression}}.should_raise #{exceptions[index][0]}"] - end - - module WithParentheses - def nil_assertion(expression) - ["(#{expression}).should_be_nil"] + module NewAPI + def raise_assertion(expression, exceptions, index) + ["lambda{#{expression}}.should raise_error(#{exceptions[index][0]})"] end - - def value_assertions(klass_txt, value_txt, value, expression) - case value - when Float - ["(#{expression}).should_be_close #{value.inspect}, 0.0001"] - when Numeric, String, Hash, Array, Regexp, TrueClass, FalseClass, Symbol, NilClass - ["(#{expression}).should_equal #{value_txt}"] - else - object_assertions klass_txt, value_txt, expression + + module WithParentheses + def nil_assertion(expression) + ["(#{expression}).should be_nil"] end - end - def object_assertions(klass_txt, value_txt, expression) - [ "(#{expression}).should_be_a_kind_of #{klass_txt}", - "(#{expression}.inspect).should_equal #{value_txt.inspect}" ] + def value_assertions(klass_txt, value_txt, value, expression) + case value + when Float + ["(#{expression}).should be_close(#{value.inspect}, #{FLOAT_TOLERANCE})"] + when Numeric, String, Hash, Array, Regexp, TrueClass, FalseClass, Symbol, NilClass + ["(#{expression}).should == (#{value_txt})"] + else + object_assertions klass_txt, value_txt, expression + end + end + + def object_assertions(klass_txt, value_txt, expression) + [ "(#{expression}).should be_a_kind_of(#{klass_txt})", + "(#{expression}.inspect).should == (#{value_txt.inspect})" ] + end + + def equal_assertion(expected, actual) + "(#{actual}).should == (#{expected})" + end end - def equal_assertion(expected, actual) - "(#{actual}).should_equal #{expected}" + module Poetry + def nil_assertion(expression) + ["#{expression}.should be_nil"] + end + + def value_assertions(klass_txt, value_txt, value, expression) + case value + when Float + ["#{expression}.should be_close(#{value.inspect}, #{FLOAT_TOLERANCE})"] + when Numeric, String, Hash, Array, Regexp, TrueClass, FalseClass, Symbol, NilClass + ["#{expression}.should == #{value_txt}"] + else + object_assertions klass_txt, value_txt, expression + end + end + + def object_assertions(klass_txt, value_txt, expression) + [ "#{expression}.should be_a_kind_of(#{klass_txt})", + "#{expression}.inspect.should == #{value_txt.inspect}" ] + end + + def equal_assertion(expected, actual) + "#{actual}.should == #{expected}" + end end end - module Poetry - def nil_assertion(expression) - ["#{expression}.should_be_nil"] + module OldAPI + # old rspec, use deprecated syntax + def raise_assertion(expression, exceptions, index) + ["lambda{#{expression}}.should_raise_error(#{exceptions[index][0]})"] end - def value_assertions(klass_txt, value_txt, value, expression) - case value - when Float - ["#{expression}.should_be_close #{value.inspect}, 0.0001"] - when Numeric, String, Hash, Array, Regexp, TrueClass, FalseClass, Symbol, NilClass - ["#{expression}.should_equal #{value_txt}"] - else - object_assertions klass_txt, value_txt, expression + module WithParentheses + def nil_assertion(expression) + ["(#{expression}).should_be_nil"] end - end - def object_assertions(klass_txt, value_txt, expression) - [ "#{expression}.should_be_a_kind_of #{klass_txt}", - "#{expression}.inspect.should_equal #{value_txt.inspect}" ] + def value_assertions(klass_txt, value_txt, value, expression) + case value + when Float + ["(#{expression}).should_be_close(#{value.inspect}, #{FLOAT_TOLERANCE})"] + when Numeric, String, Hash, Array, Regexp, TrueClass, FalseClass, Symbol, NilClass + ["(#{expression}).should_equal(#{value_txt})"] + else + object_assertions klass_txt, value_txt, expression + end + end + + def object_assertions(klass_txt, value_txt, expression) + [ "(#{expression}).should_be_a_kind_of(#{klass_txt})", + "(#{expression}.inspect).should_equal(#{value_txt.inspect})" ] + end + + def equal_assertion(expected, actual) + "(#{actual}).should_equal(#{expected})" + end end - def equal_assertion(expected, actual) - "#{actual}.should_equal #{expected}" + module Poetry + def nil_assertion(expression) + ["#{expression}.should_be_nil"] + end + + def value_assertions(klass_txt, value_txt, value, expression) + case value + when Float + ["#{expression}.should_be_close #{value.inspect}, #{FLOAT_TOLERANCE}"] + when Numeric, String, Hash, Array, Regexp, TrueClass, FalseClass, Symbol, NilClass + ["#{expression}.should_equal #{value_txt}"] + else + object_assertions klass_txt, value_txt, expression + end + end + + def object_assertions(klass_txt, value_txt, expression) + [ "#{expression}.should_be_a_kind_of #{klass_txt}", + "#{expression}.inspect.should_equal #{value_txt.inspect}" ] + end + + def equal_assertion(expected, actual) + "#{actual}.should_equal #{expected}" + end end end + + end +class XMPExpectationsFilter < XMPTestUnitFilter + def initialize(x={}) + super(x.merge(:_no_extend_module => true)) + @warnings = false + end + + def expectation(expected, actual) + < 'unit', 'controllers' => 'functional' } + RAILS_TESTNAME2MVC = RAILS_MVC2TESTNAME.invert + def test_file_00_rails(implementation, basedir, dir, node) # rails + if m = %r!app/(models|controllers)/(.+)\.rb$!.match(implementation) + "%stest/%s/%s_test.rb" % [ m.pre_match, RAILS_MVC2TESTNAME[m[1]], m[2] ] + end + end + + def test_file_05_rails_lib(implementation, basedir, dir, node) + if basedir and File.directory?( File.join(basedir, "app") ) + "#{basedir}test/unit/test_#{node}.rb" + end + end + + def test_file_10_no_match(implementation, basedir, dir, node) + if [basedir, dir, node].all?{|x| x.nil?} + "#{File.dirname(implementation)}/test_#{File.basename(implementation)}" + end + end + + def test_file_20_simple(implementation, basedir, dir, node) # test/test_NODE.rb + exist "#{basedir}test/test_#{node}.rb" + end + + def test_file_30_flat(implementation, basedir, dir, node) # lib/XXX/NODE.rb -> test/test_NODE.rb + exist "#{basedir}test/test_#{node}.rb" if dir + end + + def test_file_99_autotest_default(implementation, basedir, dir, node) # lib/XXX/NODE.rb -> test/XXX/test_NODE.rb + "#{basedir}test/#{dir}test_#{node}.rb" + end + + def implementation_file_00_rails(test, basedir, dir, node) + if m = %r!test/(unit|functional)/(.+)_test.rb$!.match(test) + "%sapp/%s/%s.rb" % [ m.pre_match, RAILS_TESTNAME2MVC[m[1]], m[2] ] + end + end + + def implementation_file_10_no_match(test, basename, dir, node) + if dir == nil and node == nil and test =~ %r!/test_(.+)\.rb$! + test.sub("/test_", "/") + end + end + + def implementation_file_20(test, basedir, dir, node) + exist("#{basedir}lib/#{dir}#{node}.rb") + end + + def implementation_file_30_flat(test, basedir, dir, node) + Dir[ "#{basedir}lib/**/#{node}.rb" ].first + end + + def implementation_file_99_default(test, basedir, dir, node) + "#{basedir}lib/#{dir}#{node}.rb" + end + +end diff --git a/Support/vendor/rcodetools/rcodetools.el b/Support/vendor/rcodetools/rcodetools.el index 4c2e441..e5c90af 100644 --- a/Support/vendor/rcodetools/rcodetools.el +++ b/Support/vendor/rcodetools/rcodetools.el @@ -1,10 +1,10 @@ ;;; rcodetools.el -- annotation / accurate completion / browsing documentation -;;; Copyright (c) 2006 rubikitch +;;; Copyright (c) 2006-2008 rubikitch ;;; ;;; Use and distribution subject to the terms of the Ruby license. -(defvar xmpfilter-command-name "ruby -S xmpfilter --dev --detect-rbtest" +(defvar xmpfilter-command-name "ruby -S xmpfilter --dev --fork --detect-rbtest" "The xmpfilter command name.") (defvar rct-doc-command-name "ruby -S rct-doc --dev --fork --detect-rbtest" "The rct-doc command name.") @@ -12,6 +12,7 @@ "The rct-complete command name.") (defvar ruby-toggle-file-command-name "ruby -S ruby-toggle-file" "The ruby-toggle-file command name.") +(defvar rct-fork-command-name "ruby -S rct-fork") (defvar rct-option-history nil) ;internal (defvar rct-option-local nil) ;internal (make-variable-buffer-local 'rct-option-local) @@ -55,26 +56,47 @@ (read-from-minibuffer "rcodetools option: " option nil nil 'rct-option-history)) option)))) +(defun rct-shell-command (command &optional buffer) + "Replacement for `(shell-command-on-region (point-min) (point-max) command buffer t' because of encoding problem." + (let ((input-rb (concat (make-temp-name "xmptmp-in") ".rb")) + (output-rb (concat (make-temp-name "xmptmp-out") ".rb")) + (coding-system-for-read buffer-file-coding-system)) + (write-region (point-min) (point-max) input-rb nil 'nodisp) + (shell-command + (rct-debuglog (format "%s %s > %s" command input-rb output-rb)) + t " *rct-error*") + (with-current-buffer (or buffer (current-buffer)) + (insert-file-contents output-rb nil nil nil t)) + (delete-file input-rb) + (delete-file output-rb))) + +(defvar xmpfilter-command-function 'xmpfilter-command) (defun xmp (&optional option) "Run xmpfilter for annotation/test/spec on whole buffer. See also `rct-interactive'. " (interactive (rct-interactive)) (rct-save-position - (lambda () (shell-command-on-region (point-min) (point-max) (xmpfilter-command option) t t " *rct-error*")))) + (lambda () + (rct-shell-command (funcall xmpfilter-command-function option))))) (defun xmpfilter-command (&optional option) "The xmpfilter command line, DWIM." (setq option (or option "")) - (cond ((save-excursion - (goto-char 1) - (search-forward "< Test::Unit::TestCase" nil t)) - (format "%s --unittest %s" xmpfilter-command-name option)) - ((save-excursion - (goto-char 1) - (re-search-forward "^context.+do$" nil t)) - (format "%s --spec %s" xmpfilter-command-name option)) - (t - (format "%s %s" xmpfilter-command-name option)))) + (flet ((in-block (beg-re) + (save-excursion + (goto-char (point-min)) + (when (re-search-forward beg-re nil t) + (let ((s (point)) e) + (when (re-search-forward "^end\n" nil t) + (setq e (point)) + (goto-char s) + (re-search-forward "# => *$" e t))))))) + (cond ((in-block "^class.+< Test::Unit::TestCase$") + (format "%s --unittest %s" xmpfilter-command-name option)) + ((in-block "^\\(describe\\|context\\).+do$") + (format "%s --spec %s" xmpfilter-command-name option)) + (t + (format "%s %s" xmpfilter-command-name option))))) ;;;; Completion (defvar rct-method-completion-table nil) ;internal @@ -130,13 +152,17 @@ See also `rct-interactive'." "Execute rct-complete/rct-doc and evaluate the output." (let ((eval-buffer (get-buffer-create " *rct-eval*"))) ;; copy to temporary buffer to do completion at non-EOL. - (shell-command-on-region - (point-min) (point-max) - (rct-debuglog (format "%s %s %s --line=%d --column=%d %s" - command opt (or rct-option-local "") - (rct-current-line) (current-column) - (if rct-use-test-script (rct-test-script-option-string) ""))) - eval-buffer nil " *rct-error*") + (rct-shell-command + (format "%s %s %s --line=%d --column=%d %s" + command opt (or rct-option-local "") + (rct-current-line) + ;; specify column in BYTE + (string-bytes + (encode-coding-string + (buffer-substring (point-at-bol) (point)) + buffer-file-coding-system)) + (if rct-use-test-script (rct-test-script-option-string) "")) + eval-buffer) (message "") (eval (with-current-buffer eval-buffer (goto-char 1) @@ -149,8 +175,10 @@ See also `rct-interactive'." "" (let ((test-buf (rct-find-test-script-buffer)) (bfn buffer-file-name) - t-opt test-filename) - (if test-buf + bfn2 t-opt test-filename) + (if (and test-buf + (setq bfn2 (buffer-local-value 'buffer-file-name test-buf)) + (file-exists-p bfn2)) ;; pass test script's filename and lineno (with-current-buffer test-buf (setq t-opt (format "%s@%s" buffer-file-name (rct-current-line))) @@ -213,5 +241,190 @@ See also `rct-interactive'. " (find-file (shell-command-to-string (format "%s %s" ruby-toggle-file-command-name buffer-file-name)))) +;;;; rct-fork support +(defun rct-fork (options) + "Run rct-fork. +Rct-fork makes xmpfilter and completion MUCH FASTER because it pre-loads heavy libraries. +When rct-fork is running, the mode-line indicates it to avoid unnecessary run. +To kill rct-fork process, use \\[rct-fork-kill]. +" + (interactive (list + (read-string "rct-fork options (-e CODE -I LIBDIR -r LIB): " + (rct-fork-default-options)))) + (rct-fork-kill) + (rct-fork-minor-mode 1) + (start-process-shell-command + "rct-fork" "*rct-fork*" rct-fork-command-name options)) + +(defun rct-fork-default-options () + "Default options for rct-fork by collecting requires." + (mapconcat + (lambda (lib) (format "-r %s" lib)) + (save-excursion + (goto-char (point-min)) + (loop while (re-search-forward "\\ ['\"]\\([^'\"]+\\)['\"]" nil t) + collect (match-string-no-properties 1))) + " ")) + +(defun rct-fork-kill () + "Kill rct-fork process invoked by \\[rct-fork]." + (interactive) + (when rct-fork-minor-mode + (rct-fork-minor-mode -1) + (interrupt-process "rct-fork"))) +(define-minor-mode rct-fork-minor-mode + "This minor mode is turned on when rct-fork is run. +It is nothing but an indicator." + :lighter " " :global t) + +;;;; unit tests +(when (and (fboundp 'expectations)) + (require 'ruby-mode) + (require 'el-mock nil t) + (expectations + (desc "comment-dwim advice") + (expect "# =>" + (with-temp-buffer + (ruby-mode) + (setq last-command nil) + (call-interactively 'comment-dwim) + (setq last-command 'comment-dwim) + (call-interactively 'comment-dwim) + (buffer-string))) + (expect (regexp "^1 +# =>") + (with-temp-buffer + (ruby-mode) + (insert "1") + (setq last-command nil) + (call-interactively 'comment-dwim) + (setq last-command 'comment-dwim) + (call-interactively 'comment-dwim) + (buffer-string))) + + (desc "rct-current-line") + (expect 1 + (with-temp-buffer + (rct-current-line))) + (expect 1 + (with-temp-buffer + (insert "1") + (rct-current-line))) + (expect 2 + (with-temp-buffer + (insert "1\n") + (rct-current-line))) + (expect 2 + (with-temp-buffer + (insert "1\n2") + (rct-current-line))) + + (desc "rct-save-position") + (expect (mock (set-window-start * 7) => nil) + (stub window-start => 7) + (with-temp-buffer + (insert "abcdef\nghi") + (rct-save-position #'ignore))) + (expect 2 + (with-temp-buffer + (stub window-start => 1) + (stub set-window-start => nil) + (insert "abcdef\nghi") + (rct-save-position #'ignore) + (rct-current-line))) + (expect 3 + (with-temp-buffer + (stub window-start => 1) + (stub set-window-start => nil) + (insert "abcdef\nghi") + (rct-save-position #'ignore) + (current-column))) + + (desc "rct-interactive") + (expect '("read") + (let ((current-prefix-arg t)) + (stub read-from-minibuffer => "read") + (rct-interactive))) + (expect '("-S ruby19") + (let ((current-prefix-arg nil) + (rct-option-local "-S ruby19")) + (stub read-from-minibuffer => "read") + (rct-interactive))) + (expect '("") + (let ((current-prefix-arg nil) + (rct-option-local)) + (stub read-from-minibuffer => "read") + (rct-interactive))) + + (desc "rct-shell-command") + (expect "1+1 # => 2\n" + (with-temp-buffer + (insert "1+1 # =>\n") + (rct-shell-command "xmpfilter") + (buffer-string))) + + (desc "xmp") + + (desc "xmpfilter-command") + (expect "xmpfilter --rails" + (let ((xmpfilter-command-name "xmpfilter")) + (with-temp-buffer + (insert "class TestFoo < Test::Unit::TestCase\n") + (xmpfilter-command "--rails")))) + (expect "xmpfilter " + (let ((xmpfilter-command-name "xmpfilter")) + (with-temp-buffer + (insert "context 'foo' do\n") + (xmpfilter-command)))) + (expect "xmpfilter " + (let ((xmpfilter-command-name "xmpfilter")) + (with-temp-buffer + (insert "describe Array do\n") + (xmpfilter-command)))) + (expect "xmpfilter --unittest --rails" + (let ((xmpfilter-command-name "xmpfilter")) + (with-temp-buffer + (insert "class TestFoo < Test::Unit::TestCase\n" + " def test_0\n" + " 1 + 1 # =>\n" + " end\n" + "end\n") + (xmpfilter-command "--rails")))) + (expect "xmpfilter --spec " + (let ((xmpfilter-command-name "xmpfilter")) + (with-temp-buffer + (insert "context 'foo' do\n" + " specify \"foo\" do\n" + " 1 + 1 # =>\n" + " end\n" + "end\n") + (xmpfilter-command)))) + (expect "xmpfilter --spec " + (let ((xmpfilter-command-name "xmpfilter")) + (with-temp-buffer + (insert "describe Array do\n" + " it \"foo\" do\n" + " [1] + [1] # =>\n" + " end\n" + "end\n") + (xmpfilter-command)))) + (expect "xmpfilter " + (let ((xmpfilter-command-name "xmpfilter")) + (with-temp-buffer + (insert "1 + 2\n") + (xmpfilter-command)))) + + (desc "rct-fork") + (expect t + (stub start-process-shell-command => t) + (stub interrupt-process => t) + (rct-fork "-r activesupport") + rct-fork-minor-mode) + (expect nil + (stub start-process-shell-command => t) + (stub interrupt-process => t) + (rct-fork "-r activesupport") + (rct-fork-kill) + rct-fork-minor-mode) + )) (provide 'rcodetools) diff --git a/Support/vendor/rcodetools/rcodetools.elc b/Support/vendor/rcodetools/rcodetools.elc new file mode 100644 index 0000000..a5c67c0 Binary files /dev/null and b/Support/vendor/rcodetools/rcodetools.elc differ diff --git a/Support/vendor/rcodetools/rcodetools.gif b/Support/vendor/rcodetools/rcodetools.gif new file mode 100644 index 0000000..7c35fe7 Binary files /dev/null and b/Support/vendor/rcodetools/rcodetools.gif differ diff --git a/Support/vendor/rcodetools/rcodetools.sxmp b/Support/vendor/rcodetools/rcodetools.sxmp new file mode 100644 index 0000000..a81418a Binary files /dev/null and b/Support/vendor/rcodetools/rcodetools.sxmp differ diff --git a/Support/vendor/rcodetools/test/attic/test_run.rb b/Support/vendor/rcodetools/test/attic/test_run.rb new file mode 100644 index 0000000..37d83d5 --- /dev/null +++ b/Support/vendor/rcodetools/test/attic/test_run.rb @@ -0,0 +1,45 @@ +require 'test/unit' +require 'rcodetools/xmpfilter' +require 'rcodetools/xmptestunitfilter' +require 'rcodetools/completion' +require 'rcodetools/doc' +require 'rcodetools/options' +require 'stringio' + +class TestRun < Test::Unit::TestCase + include Rcodetools + DIR = File.expand_path(File.dirname(__FILE__)) + + tests = { + :simple_annotation => {:klass => XMPFilter}, + :unit_test => {:klass => XMPTestUnitFilter}, + :rspec => {:klass => XMPRSpecFilter, :interpreter => "spec"}, + :rspec_poetry => {:klass => XMPRSpecFilter, :interpreter => "spec", :use_parentheses => false}, + :no_warnings => {:klass => XMPFilter, :warnings => false}, + :bindings => {:klass => XMPTestUnitFilter, :use_parentheses => false}, + :unit_test_poetry => {:klass => XMPTestUnitFilter, :use_parentheses => false}, + :add_markers => {:klass => XMPAddMarkers}, + + :completion => {:klass => XMPCompletionFilter, :lineno => 1}, + :completion_emacs => {:klass => XMPCompletionEmacsFilter, :lineno => 1}, + :completion_emacs_icicles => {:klass => XMPCompletionEmacsIciclesFilter, :lineno => 1}, + :completion_class_info => {:klass => XMPCompletionClassInfoFilter, :lineno => 1}, + :completion_class_info_no_candidates => {:klass => XMPCompletionClassInfoFilter, :lineno => 1}, + + :doc => {:klass => XMPDocFilter, :lineno => 1}, + :refe => {:klass => XMPReFeFilter, :lineno => 1}, + :ri => {:klass => XMPRiFilter, :lineno => 1}, + :ri_emacs => {:klass => XMPRiEmacsFilter, :lineno => 1}, + :ri_vim => {:klass => XMPRiVimFilter, :lineno => 1}, + + } + tests.each_pair do |test, opts| + define_method("test_#{test}") do + inputfile = "#{DIR}/data/#{test}-input.rb" + outputfile = "#{DIR}/data/#{test}-output.rb" + sio = StringIO.new + sio.puts opts[:klass].run(File.read(inputfile), DEFAULT_OPTIONS.merge(opts)) + assert_equal(File.read(outputfile), sio.string) + end + end +end diff --git a/Support/vendor/rcodetools/test/data/attic/add_markers-input.rb b/Support/vendor/rcodetools/test/data/attic/add_markers-input.rb new file mode 100644 index 0000000..33a508e --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/add_markers-input.rb @@ -0,0 +1,2 @@ +1+1 +2+3 diff --git a/Support/vendor/rcodetools/test/data/attic/add_markers-output.rb b/Support/vendor/rcodetools/test/data/attic/add_markers-output.rb new file mode 100644 index 0000000..fe8fd61 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/add_markers-output.rb @@ -0,0 +1,2 @@ +1+1 # => +2+3 # => diff --git a/Support/vendor/rcodetools/test/data/attic/bindings-input.rb b/Support/vendor/rcodetools/test/data/attic/bindings-input.rb new file mode 100644 index 0000000..90e97e2 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/bindings-input.rb @@ -0,0 +1,26 @@ + +require 'test/unit' + +class TestFoo < Test::Unit::TestCase + def setup + @o = [] + end + + def test_foo + a = 1 + b = a + b # => + end + + def test_arr + last = 1 + @o << last + @o.last # => + end + + def test_bar + a = b = c = 1 + d = a + d # => + end +end diff --git a/Support/vendor/rcodetools/test/data/attic/bindings-output.rb b/Support/vendor/rcodetools/test/data/attic/bindings-output.rb new file mode 100644 index 0000000..cbea3c0 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/bindings-output.rb @@ -0,0 +1,31 @@ + +require 'test/unit' + +class TestFoo < Test::Unit::TestCase + def setup + @o = [] + end + + def test_foo + a = 1 + b = a + assert_equal a, b + assert_equal 1, b + end + + def test_arr + last = 1 + @o << last + assert_equal last, @o.last + assert_equal 1, @o.last + end + + def test_bar + a = b = c = 1 + d = a + assert_equal a, d + assert_equal b, d + assert_equal c, d + assert_equal 1, d + end +end diff --git a/Support/vendor/rcodetools/test/data/attic/completion-input.rb b/Support/vendor/rcodetools/test/data/attic/completion-input.rb new file mode 100644 index 0000000..2dcaa3f --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/completion-input.rb @@ -0,0 +1 @@ +Array.new(3).uni diff --git a/Support/vendor/rcodetools/test/data/attic/completion-output.rb b/Support/vendor/rcodetools/test/data/attic/completion-output.rb new file mode 100644 index 0000000..9546ff3 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/completion-output.rb @@ -0,0 +1,2 @@ +uniq +uniq! diff --git a/Support/vendor/rcodetools/test/data/attic/completion_class_info-input.rb b/Support/vendor/rcodetools/test/data/attic/completion_class_info-input.rb new file mode 100644 index 0000000..6ea2364 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/completion_class_info-input.rb @@ -0,0 +1 @@ +Array.new(3).s \ No newline at end of file diff --git a/Support/vendor/rcodetools/test/data/attic/completion_class_info-output.rb b/Support/vendor/rcodetools/test/data/attic/completion_class_info-output.rb new file mode 100644 index 0000000..8c604b3 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/completion_class_info-output.rb @@ -0,0 +1,10 @@ +select Array#select +send Object#send +shift Array#shift +singleton_methods Object#singleton_methods +size Array#size +slice Array#slice +slice! Array#slice! +sort Array#sort +sort! Array#sort! +sort_by Enumerable#sort_by diff --git a/Support/vendor/rcodetools/test/data/attic/completion_class_info_no_candidates-input.rb b/Support/vendor/rcodetools/test/data/attic/completion_class_info_no_candidates-input.rb new file mode 100644 index 0000000..4666cc0 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/completion_class_info_no_candidates-input.rb @@ -0,0 +1 @@ +Array.new(3).nonexisten \ No newline at end of file diff --git a/Support/vendor/rcodetools/test/data/attic/completion_class_info_no_candidates-output.rb b/Support/vendor/rcodetools/test/data/attic/completion_class_info_no_candidates-output.rb new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/completion_class_info_no_candidates-output.rb @@ -0,0 +1 @@ + diff --git a/Support/vendor/rcodetools/test/data/attic/completion_detect_rbtest-input.rb b/Support/vendor/rcodetools/test/data/attic/completion_detect_rbtest-input.rb new file mode 100755 index 0000000..c4d92ca --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/completion_detect_rbtest-input.rb @@ -0,0 +1,7 @@ +#!/usr/bin/env ruby +=begin test_bar +assert_equal "BAR", bar("bar") +=end +def bar(s) + s.upca +end diff --git a/Support/vendor/rcodetools/test/data/attic/completion_detect_rbtest-output.rb b/Support/vendor/rcodetools/test/data/attic/completion_detect_rbtest-output.rb new file mode 100644 index 0000000..c3d421a --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/completion_detect_rbtest-output.rb @@ -0,0 +1,2 @@ +upcase +upcase! diff --git a/Support/vendor/rcodetools/test/data/attic/completion_detect_rbtest2-input.rb b/Support/vendor/rcodetools/test/data/attic/completion_detect_rbtest2-input.rb new file mode 100644 index 0000000..2dcaa3f --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/completion_detect_rbtest2-input.rb @@ -0,0 +1 @@ +Array.new(3).uni diff --git a/Support/vendor/rcodetools/test/data/attic/completion_detect_rbtest2-output.rb b/Support/vendor/rcodetools/test/data/attic/completion_detect_rbtest2-output.rb new file mode 100644 index 0000000..9546ff3 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/completion_detect_rbtest2-output.rb @@ -0,0 +1,2 @@ +uniq +uniq! diff --git a/Support/vendor/rcodetools/test/data/attic/completion_emacs-input.rb b/Support/vendor/rcodetools/test/data/attic/completion_emacs-input.rb new file mode 100644 index 0000000..2dcaa3f --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/completion_emacs-input.rb @@ -0,0 +1 @@ +Array.new(3).uni diff --git a/Support/vendor/rcodetools/test/data/attic/completion_emacs-output.rb b/Support/vendor/rcodetools/test/data/attic/completion_emacs-output.rb new file mode 100644 index 0000000..c83366a --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/completion_emacs-output.rb @@ -0,0 +1,6 @@ +(progn +(setq rct-method-completion-table '(("uniq") ("uniq!") )) +(setq alist '(("uniq\t[Array#uniq]") ("uniq!\t[Array#uniq!]") )) +(setq pattern "uni") +(try-completion pattern rct-method-completion-table nil) +) diff --git a/Support/vendor/rcodetools/test/data/attic/completion_emacs_icicles-input.rb b/Support/vendor/rcodetools/test/data/attic/completion_emacs_icicles-input.rb new file mode 100644 index 0000000..aa062b7 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/completion_emacs_icicles-input.rb @@ -0,0 +1 @@ +1.div diff --git a/Support/vendor/rcodetools/test/data/attic/completion_emacs_icicles-output.rb b/Support/vendor/rcodetools/test/data/attic/completion_emacs_icicles-output.rb new file mode 100644 index 0000000..e4747ae --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/completion_emacs_icicles-output.rb @@ -0,0 +1,6 @@ +(progn +(setq rct-method-completion-table '(("div\t[Fixnum#div]") ("divmod\t[Fixnum#divmod]") )) +(setq alist '(("div" . "Fixnum#div")("divmod" . "Fixnum#divmod"))) +(setq pattern "div") +(setq klass "Fixnum") +) diff --git a/Support/vendor/rcodetools/test/data/attic/completion_in_method-input.rb b/Support/vendor/rcodetools/test/data/attic/completion_in_method-input.rb new file mode 100644 index 0000000..1644080 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/completion_in_method-input.rb @@ -0,0 +1,3 @@ +def fooz + [].lengt +end diff --git a/Support/vendor/rcodetools/test/data/attic/completion_in_method-output.rb b/Support/vendor/rcodetools/test/data/attic/completion_in_method-output.rb new file mode 100644 index 0000000..7f5e3b6 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/completion_in_method-output.rb @@ -0,0 +1 @@ +length diff --git a/Support/vendor/rcodetools/test/data/attic/completion_in_method-test.rb b/Support/vendor/rcodetools/test/data/attic/completion_in_method-test.rb new file mode 100644 index 0000000..1edef97 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/completion_in_method-test.rb @@ -0,0 +1,6 @@ +require 'test/unit' +class TestFooz < Test::Unit::TestCase + def test_fooz + assert_equal(0, fooz) + end +end diff --git a/Support/vendor/rcodetools/test/data/attic/completion_rbtest-input.rb b/Support/vendor/rcodetools/test/data/attic/completion_rbtest-input.rb new file mode 100755 index 0000000..c4d92ca --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/completion_rbtest-input.rb @@ -0,0 +1,7 @@ +#!/usr/bin/env ruby +=begin test_bar +assert_equal "BAR", bar("bar") +=end +def bar(s) + s.upca +end diff --git a/Support/vendor/rcodetools/test/data/attic/completion_rbtest-output.rb b/Support/vendor/rcodetools/test/data/attic/completion_rbtest-output.rb new file mode 100644 index 0000000..c3d421a --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/completion_rbtest-output.rb @@ -0,0 +1,2 @@ +upcase +upcase! diff --git a/Support/vendor/rcodetools/test/data/attic/doc-input.rb b/Support/vendor/rcodetools/test/data/attic/doc-input.rb new file mode 100644 index 0000000..624aca7 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/doc-input.rb @@ -0,0 +1 @@ +[].length diff --git a/Support/vendor/rcodetools/test/data/attic/doc-output.rb b/Support/vendor/rcodetools/test/data/attic/doc-output.rb new file mode 100644 index 0000000..ca542db --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/doc-output.rb @@ -0,0 +1 @@ +Array#length diff --git a/Support/vendor/rcodetools/test/data/attic/doc_detect_rbtest-input.rb b/Support/vendor/rcodetools/test/data/attic/doc_detect_rbtest-input.rb new file mode 100644 index 0000000..624aca7 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/doc_detect_rbtest-input.rb @@ -0,0 +1 @@ +[].length diff --git a/Support/vendor/rcodetools/test/data/attic/doc_detect_rbtest-output.rb b/Support/vendor/rcodetools/test/data/attic/doc_detect_rbtest-output.rb new file mode 100644 index 0000000..ca542db --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/doc_detect_rbtest-output.rb @@ -0,0 +1 @@ +Array#length diff --git a/Support/vendor/rcodetools/test/data/attic/doc_detect_rbtest2-input.rb b/Support/vendor/rcodetools/test/data/attic/doc_detect_rbtest2-input.rb new file mode 100755 index 0000000..bf97ffe --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/doc_detect_rbtest2-input.rb @@ -0,0 +1,7 @@ +#!/usr/bin/env ruby +=begin test_bar +assert_equal "BAR", bar("bar") +=end +def bar(s) + s.upcase +end diff --git a/Support/vendor/rcodetools/test/data/attic/doc_detect_rbtest2-output.rb b/Support/vendor/rcodetools/test/data/attic/doc_detect_rbtest2-output.rb new file mode 100644 index 0000000..5791850 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/doc_detect_rbtest2-output.rb @@ -0,0 +1 @@ +String#upcase diff --git a/Support/vendor/rcodetools/test/data/attic/doc_rbtest-input.rb b/Support/vendor/rcodetools/test/data/attic/doc_rbtest-input.rb new file mode 100755 index 0000000..bf97ffe --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/doc_rbtest-input.rb @@ -0,0 +1,7 @@ +#!/usr/bin/env ruby +=begin test_bar +assert_equal "BAR", bar("bar") +=end +def bar(s) + s.upcase +end diff --git a/Support/vendor/rcodetools/test/data/attic/doc_rbtest-output.rb b/Support/vendor/rcodetools/test/data/attic/doc_rbtest-output.rb new file mode 100644 index 0000000..5791850 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/doc_rbtest-output.rb @@ -0,0 +1 @@ +String#upcase diff --git a/Support/vendor/rcodetools/test/data/attic/no_warnings-input.rb b/Support/vendor/rcodetools/test/data/attic/no_warnings-input.rb new file mode 100644 index 0000000..514e18c --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/no_warnings-input.rb @@ -0,0 +1,3 @@ +A = 1 +A = 1 +p (1) diff --git a/Support/vendor/rcodetools/test/data/attic/no_warnings-output.rb b/Support/vendor/rcodetools/test/data/attic/no_warnings-output.rb new file mode 100644 index 0000000..27a7238 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/no_warnings-output.rb @@ -0,0 +1,4 @@ +A = 1 +A = 1 +p (1) +# >> 1 diff --git a/Support/vendor/rcodetools/test/data/attic/refe-input.rb b/Support/vendor/rcodetools/test/data/attic/refe-input.rb new file mode 100644 index 0000000..624aca7 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/refe-input.rb @@ -0,0 +1 @@ +[].length diff --git a/Support/vendor/rcodetools/test/data/attic/refe-output.rb b/Support/vendor/rcodetools/test/data/attic/refe-output.rb new file mode 100644 index 0000000..8653c3d --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/refe-output.rb @@ -0,0 +1 @@ +refe 'Array#length' diff --git a/Support/vendor/rcodetools/test/data/attic/ri-input.rb b/Support/vendor/rcodetools/test/data/attic/ri-input.rb new file mode 100644 index 0000000..624aca7 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/ri-input.rb @@ -0,0 +1 @@ +[].length diff --git a/Support/vendor/rcodetools/test/data/attic/ri-output.rb b/Support/vendor/rcodetools/test/data/attic/ri-output.rb new file mode 100644 index 0000000..f1ba49e --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/ri-output.rb @@ -0,0 +1 @@ +ri 'Array#length' diff --git a/Support/vendor/rcodetools/test/data/attic/ri_emacs-input.rb b/Support/vendor/rcodetools/test/data/attic/ri_emacs-input.rb new file mode 100644 index 0000000..624aca7 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/ri_emacs-input.rb @@ -0,0 +1 @@ +[].length diff --git a/Support/vendor/rcodetools/test/data/attic/ri_emacs-output.rb b/Support/vendor/rcodetools/test/data/attic/ri_emacs-output.rb new file mode 100644 index 0000000..5f7389f --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/ri_emacs-output.rb @@ -0,0 +1 @@ +(rct-find-tag-or-ri "Array#length") diff --git a/Support/vendor/rcodetools/test/data/attic/ri_vim-input.rb b/Support/vendor/rcodetools/test/data/attic/ri_vim-input.rb new file mode 100644 index 0000000..624aca7 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/ri_vim-input.rb @@ -0,0 +1 @@ +[].length diff --git a/Support/vendor/rcodetools/test/data/attic/ri_vim-output.rb b/Support/vendor/rcodetools/test/data/attic/ri_vim-output.rb new file mode 100644 index 0000000..8e71a9a --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/ri_vim-output.rb @@ -0,0 +1 @@ +call RCT_find_tag_or_ri("Array#length") diff --git a/Support/vendor/rcodetools/test/data/attic/rspec-input.rb b/Support/vendor/rcodetools/test/data/attic/rspec-input.rb new file mode 100644 index 0000000..c57b23c --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/rspec-input.rb @@ -0,0 +1,48 @@ + +class X + Y = Struct.new(:a) + def foo(b); b ? Y.new(2) : 2 end + def bar; raise "No good" end + def baz; nil end + def fubar(x); x ** 2.0 + 1 end + def babar; [1,2] end + A = 1 + A = 1 +end + + +describe "xmpfilter's expectation expansion" do + before do + @o = X.new + end + + it "should expand should == expectations" do + @o.foo(true) # => + @o.foo(true).a # => + @o.foo(false) # => + end + + it "should expand should raise_error expectations" do + @o.bar # => + end + + it "should expand should be_nil expectations" do + @o.baz # => + end + + it "should expand correct expectations for complex values" do + @o.babar # => + end + + it "should expand should be_close expectations" do + @o.fubar(10) # => + end +end + +describe "xmpfilter's automagic binding detection" do + it "should expand should == expectations" do + a = b = c = 1 + d = a + d # => + end +end diff --git a/Support/vendor/rcodetools/test/data/attic/rspec-output.rb b/Support/vendor/rcodetools/test/data/attic/rspec-output.rb new file mode 100644 index 0000000..00abb88 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/rspec-output.rb @@ -0,0 +1,52 @@ + +class X + Y = Struct.new(:a) + def foo(b); b ? Y.new(2) : 2 end + def bar; raise "No good" end + def baz; nil end + def fubar(x); x ** 2.0 + 1 end + def babar; [1,2] end + A = 1 + A = 1 # !> already initialized constant A +end + + +describe "xmpfilter's expectation expansion" do + before do + @o = X.new + end + + it "should expand should == expectations" do + (@o.foo(true)).should be_a_kind_of(X::Y) + (@o.foo(true).inspect).should == ("#") + (@o.foo(true).a).should == (2) + (@o.foo(false)).should == (2) + end + + it "should expand should raise_error expectations" do + lambda{@o.bar}.should raise_error(RuntimeError) + end + + it "should expand should be_nil expectations" do + (@o.baz).should be_nil + end + + it "should expand correct expectations for complex values" do + (@o.babar).should == ([1, 2]) + end + + it "should expand should be_close expectations" do + (@o.fubar(10)).should be_close(101.0, 0.0001) + end +end + +describe "xmpfilter's automagic binding detection" do + it "should expand should == expectations" do + a = b = c = 1 + d = a + (d).should == (a) + (d).should == (b) + (d).should == (c) + (d).should == (1) + end +end diff --git a/Support/vendor/rcodetools/test/data/attic/rspec_poetry-input.rb b/Support/vendor/rcodetools/test/data/attic/rspec_poetry-input.rb new file mode 100644 index 0000000..c57b23c --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/rspec_poetry-input.rb @@ -0,0 +1,48 @@ + +class X + Y = Struct.new(:a) + def foo(b); b ? Y.new(2) : 2 end + def bar; raise "No good" end + def baz; nil end + def fubar(x); x ** 2.0 + 1 end + def babar; [1,2] end + A = 1 + A = 1 +end + + +describe "xmpfilter's expectation expansion" do + before do + @o = X.new + end + + it "should expand should == expectations" do + @o.foo(true) # => + @o.foo(true).a # => + @o.foo(false) # => + end + + it "should expand should raise_error expectations" do + @o.bar # => + end + + it "should expand should be_nil expectations" do + @o.baz # => + end + + it "should expand correct expectations for complex values" do + @o.babar # => + end + + it "should expand should be_close expectations" do + @o.fubar(10) # => + end +end + +describe "xmpfilter's automagic binding detection" do + it "should expand should == expectations" do + a = b = c = 1 + d = a + d # => + end +end diff --git a/Support/vendor/rcodetools/test/data/attic/rspec_poetry-output.rb b/Support/vendor/rcodetools/test/data/attic/rspec_poetry-output.rb new file mode 100644 index 0000000..907b305 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/rspec_poetry-output.rb @@ -0,0 +1,52 @@ + +class X + Y = Struct.new(:a) + def foo(b); b ? Y.new(2) : 2 end + def bar; raise "No good" end + def baz; nil end + def fubar(x); x ** 2.0 + 1 end + def babar; [1,2] end + A = 1 + A = 1 # !> already initialized constant A +end + + +describe "xmpfilter's expectation expansion" do + before do + @o = X.new + end + + it "should expand should == expectations" do + @o.foo(true).should be_a_kind_of(X::Y) + @o.foo(true).inspect.should == "#" + @o.foo(true).a.should == 2 + @o.foo(false).should == 2 + end + + it "should expand should raise_error expectations" do + lambda{@o.bar}.should raise_error(RuntimeError) + end + + it "should expand should be_nil expectations" do + @o.baz.should be_nil + end + + it "should expand correct expectations for complex values" do + @o.babar.should == [1, 2] + end + + it "should expand should be_close expectations" do + @o.fubar(10).should be_close(101.0, 0.0001) + end +end + +describe "xmpfilter's automagic binding detection" do + it "should expand should == expectations" do + a = b = c = 1 + d = a + d.should == a + d.should == b + d.should == c + d.should == 1 + end +end diff --git a/Support/vendor/rcodetools/test/data/attic/simple_annotation-input.rb b/Support/vendor/rcodetools/test/data/attic/simple_annotation-input.rb new file mode 100644 index 0000000..e4eb385 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/simple_annotation-input.rb @@ -0,0 +1,8 @@ + +a = 1 +10.times do |i| + i ** 2 # => + a += i +end +A = 1 +A = 1 diff --git a/Support/vendor/rcodetools/test/data/attic/simple_annotation-output.rb b/Support/vendor/rcodetools/test/data/attic/simple_annotation-output.rb new file mode 100644 index 0000000..41cd4c0 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/simple_annotation-output.rb @@ -0,0 +1,8 @@ + +a = 1 +10.times do |i| + i ** 2 # => 0, 1, 4, 9, 16, 25, 36, 49, 64, 81 + a += i +end +A = 1 +A = 1 # !> already initialized constant A diff --git a/Support/vendor/rcodetools/test/data/attic/unit_test-input.rb b/Support/vendor/rcodetools/test/data/attic/unit_test-input.rb new file mode 100644 index 0000000..d9d02cd --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/unit_test-input.rb @@ -0,0 +1,50 @@ + +class X + Y = Struct.new(:a) + def foo(b); b ? Y.new(2) : 2 end + def bar; raise "No good" end + def baz; nil end + def fubar(x); x ** 2.0 + 1 end + def babar; [1,2] end + A = 1 + A = 1 + def difftype() [1, "s"] end +end + + +require 'test/unit' +class Test_X < Test::Unit::TestCase + def setup + @o = X.new + end + + def test_foo + @o.foo(true) # => + @o.foo(true).a # => + @o.foo(false) # => + end + + def test_bar + @o.bar # => + end + + def test_baz + @o.baz # => + end + + def test_babar + @o.babar # => + end + + def test_fubar + @o.fubar(10) # => + end + + def test_difftype + for x in @o.difftype + x # => + end + end + +end + diff --git a/Support/vendor/rcodetools/test/data/attic/unit_test-output.rb b/Support/vendor/rcodetools/test/data/attic/unit_test-output.rb new file mode 100644 index 0000000..49f4e63 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/unit_test-output.rb @@ -0,0 +1,52 @@ + +class X + Y = Struct.new(:a) + def foo(b); b ? Y.new(2) : 2 end + def bar; raise "No good" end + def baz; nil end + def fubar(x); x ** 2.0 + 1 end + def babar; [1,2] end + A = 1 + A = 1 # !> already initialized constant A + def difftype() [1, "s"] end +end + + +require 'test/unit' +class Test_X < Test::Unit::TestCase + def setup + @o = X.new + end + + def test_foo + assert_kind_of(X::Y, @o.foo(true)) + assert_equal("#", @o.foo(true).inspect) + assert_equal(2, @o.foo(true).a) + assert_equal(2, @o.foo(false)) + end + + def test_bar + assert_raise(RuntimeError){@o.bar} + end + + def test_baz + assert_nil(@o.baz) + end + + def test_babar + assert_equal([1, 2], @o.babar) + end + + def test_fubar + assert_in_delta(101.0, @o.fubar(10), 0.0001) + end + + def test_difftype + for x in @o.difftype + #xmpfilter: WARNING!! extra values ignored + assert_equal(1, x) + end + end + +end + diff --git a/Support/vendor/rcodetools/test/data/attic/unit_test_detect_rbtest-input.rb b/Support/vendor/rcodetools/test/data/attic/unit_test_detect_rbtest-input.rb new file mode 100644 index 0000000..d9d02cd --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/unit_test_detect_rbtest-input.rb @@ -0,0 +1,50 @@ + +class X + Y = Struct.new(:a) + def foo(b); b ? Y.new(2) : 2 end + def bar; raise "No good" end + def baz; nil end + def fubar(x); x ** 2.0 + 1 end + def babar; [1,2] end + A = 1 + A = 1 + def difftype() [1, "s"] end +end + + +require 'test/unit' +class Test_X < Test::Unit::TestCase + def setup + @o = X.new + end + + def test_foo + @o.foo(true) # => + @o.foo(true).a # => + @o.foo(false) # => + end + + def test_bar + @o.bar # => + end + + def test_baz + @o.baz # => + end + + def test_babar + @o.babar # => + end + + def test_fubar + @o.fubar(10) # => + end + + def test_difftype + for x in @o.difftype + x # => + end + end + +end + diff --git a/Support/vendor/rcodetools/test/data/attic/unit_test_detect_rbtest-output.rb b/Support/vendor/rcodetools/test/data/attic/unit_test_detect_rbtest-output.rb new file mode 100644 index 0000000..49f4e63 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/unit_test_detect_rbtest-output.rb @@ -0,0 +1,52 @@ + +class X + Y = Struct.new(:a) + def foo(b); b ? Y.new(2) : 2 end + def bar; raise "No good" end + def baz; nil end + def fubar(x); x ** 2.0 + 1 end + def babar; [1,2] end + A = 1 + A = 1 # !> already initialized constant A + def difftype() [1, "s"] end +end + + +require 'test/unit' +class Test_X < Test::Unit::TestCase + def setup + @o = X.new + end + + def test_foo + assert_kind_of(X::Y, @o.foo(true)) + assert_equal("#", @o.foo(true).inspect) + assert_equal(2, @o.foo(true).a) + assert_equal(2, @o.foo(false)) + end + + def test_bar + assert_raise(RuntimeError){@o.bar} + end + + def test_baz + assert_nil(@o.baz) + end + + def test_babar + assert_equal([1, 2], @o.babar) + end + + def test_fubar + assert_in_delta(101.0, @o.fubar(10), 0.0001) + end + + def test_difftype + for x in @o.difftype + #xmpfilter: WARNING!! extra values ignored + assert_equal(1, x) + end + end + +end + diff --git a/Support/vendor/rcodetools/test/data/attic/unit_test_detect_rbtest2-input.rb b/Support/vendor/rcodetools/test/data/attic/unit_test_detect_rbtest2-input.rb new file mode 100644 index 0000000..afb6ebb --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/unit_test_detect_rbtest2-input.rb @@ -0,0 +1,6 @@ +=begin test_bar +bar("bar") # => +=end +def bar(s) + s.upcase +end diff --git a/Support/vendor/rcodetools/test/data/attic/unit_test_detect_rbtest2-output.rb b/Support/vendor/rcodetools/test/data/attic/unit_test_detect_rbtest2-output.rb new file mode 100644 index 0000000..67ac1d9 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/unit_test_detect_rbtest2-output.rb @@ -0,0 +1,6 @@ +=begin test_bar +assert_equal("BAR", bar("bar")) +=end +def bar(s) + s.upcase +end diff --git a/Support/vendor/rcodetools/test/data/attic/unit_test_poetry-input.rb b/Support/vendor/rcodetools/test/data/attic/unit_test_poetry-input.rb new file mode 100644 index 0000000..d9d02cd --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/unit_test_poetry-input.rb @@ -0,0 +1,50 @@ + +class X + Y = Struct.new(:a) + def foo(b); b ? Y.new(2) : 2 end + def bar; raise "No good" end + def baz; nil end + def fubar(x); x ** 2.0 + 1 end + def babar; [1,2] end + A = 1 + A = 1 + def difftype() [1, "s"] end +end + + +require 'test/unit' +class Test_X < Test::Unit::TestCase + def setup + @o = X.new + end + + def test_foo + @o.foo(true) # => + @o.foo(true).a # => + @o.foo(false) # => + end + + def test_bar + @o.bar # => + end + + def test_baz + @o.baz # => + end + + def test_babar + @o.babar # => + end + + def test_fubar + @o.fubar(10) # => + end + + def test_difftype + for x in @o.difftype + x # => + end + end + +end + diff --git a/Support/vendor/rcodetools/test/data/attic/unit_test_poetry-output.rb b/Support/vendor/rcodetools/test/data/attic/unit_test_poetry-output.rb new file mode 100644 index 0000000..6278c25 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/unit_test_poetry-output.rb @@ -0,0 +1,52 @@ + +class X + Y = Struct.new(:a) + def foo(b); b ? Y.new(2) : 2 end + def bar; raise "No good" end + def baz; nil end + def fubar(x); x ** 2.0 + 1 end + def babar; [1,2] end + A = 1 + A = 1 # !> already initialized constant A + def difftype() [1, "s"] end +end + + +require 'test/unit' +class Test_X < Test::Unit::TestCase + def setup + @o = X.new + end + + def test_foo + assert_kind_of X::Y, @o.foo(true) + assert_equal "#", @o.foo(true).inspect + assert_equal 2, @o.foo(true).a + assert_equal 2, @o.foo(false) + end + + def test_bar + assert_raise(RuntimeError){@o.bar} + end + + def test_baz + assert_nil @o.baz + end + + def test_babar + assert_equal [1, 2], @o.babar + end + + def test_fubar + assert_in_delta 101.0, @o.fubar(10), 0.0001 + end + + def test_difftype + for x in @o.difftype + #xmpfilter: WARNING!! extra values ignored + assert_equal 1, x + end + end + +end + diff --git a/Support/vendor/rcodetools/test/data/attic/unit_test_rbtest-input.rb b/Support/vendor/rcodetools/test/data/attic/unit_test_rbtest-input.rb new file mode 100644 index 0000000..afb6ebb --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/unit_test_rbtest-input.rb @@ -0,0 +1,6 @@ +=begin test_bar +bar("bar") # => +=end +def bar(s) + s.upcase +end diff --git a/Support/vendor/rcodetools/test/data/attic/unit_test_rbtest-output.rb b/Support/vendor/rcodetools/test/data/attic/unit_test_rbtest-output.rb new file mode 100644 index 0000000..67ac1d9 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/attic/unit_test_rbtest-output.rb @@ -0,0 +1,6 @@ +=begin test_bar +assert_equal("BAR", bar("bar")) +=end +def bar(s) + s.upcase +end diff --git a/Support/vendor/rcodetools/test/data/rct-complete-TDC/completion_in_method__testmethod.taf b/Support/vendor/rcodetools/test/data/rct-complete-TDC/completion_in_method__testmethod.taf new file mode 100644 index 0000000..dfa1256 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/rct-complete-TDC/completion_in_method__testmethod.taf @@ -0,0 +1,17 @@ +========== +completion_in_method__testmethod +========== +rct-complete --filename %s --line 2 -t %s@test_fooz +========== +def fooz + [].lengt +end +========== +length +========== +require 'test/unit' +class TestFooz < Test::Unit::TestCase + def test_fooz + assert_equal(0, fooz) + end +end diff --git a/Support/vendor/rcodetools/test/data/rct-complete-TDC/completion_in_method__testscript.taf b/Support/vendor/rcodetools/test/data/rct-complete-TDC/completion_in_method__testscript.taf new file mode 100644 index 0000000..f2de8ad --- /dev/null +++ b/Support/vendor/rcodetools/test/data/rct-complete-TDC/completion_in_method__testscript.taf @@ -0,0 +1,17 @@ +========== +completion_in_method__testscript +========== +rct-complete --filename %s --line 2 -t %s +========== +def fooz + [].lengt +end +========== +length +========== +require 'test/unit' +class TestFooz < Test::Unit::TestCase + def test_fooz + assert_equal(0, fooz) + end +end diff --git a/Support/vendor/rcodetools/test/data/rct-complete-TDC/completion_in_method__wrong_testmethod.taf b/Support/vendor/rcodetools/test/data/rct-complete-TDC/completion_in_method__wrong_testmethod.taf new file mode 100644 index 0000000..989c1f4 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/rct-complete-TDC/completion_in_method__wrong_testmethod.taf @@ -0,0 +1,17 @@ +========== +completion_in_method__wrong_testmethod +========== +rct-complete --filename %s --line 2 -t %s@test_NOT_FOUND +========== +def fooz + [].lengt +end +========== + +========== +require 'test/unit' +class TestFooz < Test::Unit::TestCase + def test_fooz + assert_equal(0, fooz) + end +end diff --git a/Support/vendor/rcodetools/test/data/rct-complete/completion.taf b/Support/vendor/rcodetools/test/data/rct-complete/completion.taf new file mode 100644 index 0000000..de08a22 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/rct-complete/completion.taf @@ -0,0 +1,9 @@ +========== +completion +========== +rct-complete -C --line=1 +========== +Array.new(3).uni +========== +uniq +uniq! diff --git a/Support/vendor/rcodetools/test/data/rct-complete/completion_class_info.taf b/Support/vendor/rcodetools/test/data/rct-complete/completion_class_info.taf new file mode 100644 index 0000000..40d82fc --- /dev/null +++ b/Support/vendor/rcodetools/test/data/rct-complete/completion_class_info.taf @@ -0,0 +1,9 @@ +========== +completion_class_info +========== +rct-complete --completion-class-info --line=1 +========== +Array.new(3).sl +========== +slice Array#slice +slice! Array#slice! diff --git a/Support/vendor/rcodetools/test/data/rct-complete/completion_class_info_no_candidates.taf b/Support/vendor/rcodetools/test/data/rct-complete/completion_class_info_no_candidates.taf new file mode 100644 index 0000000..f4e8959 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/rct-complete/completion_class_info_no_candidates.taf @@ -0,0 +1,8 @@ +========== +completion_class_info_no_candidates +========== +rct-complete --completion-class-info --line=1 +========== +Array.new(3).nonexisten +========== + diff --git a/Support/vendor/rcodetools/test/data/rct-complete/completion_detect_rbtest.taf b/Support/vendor/rcodetools/test/data/rct-complete/completion_detect_rbtest.taf new file mode 100644 index 0000000..e540556 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/rct-complete/completion_detect_rbtest.taf @@ -0,0 +1,15 @@ +========== +completion_detect_rbtest +========== +rct-complete --detect-rbtest --line=6 +========== +#!/usr/bin/env ruby +=begin test_bar +assert_equal "BAR", bar("bar") +=end +def bar(s) + s.upca +end +========== +upcase +upcase! diff --git a/Support/vendor/rcodetools/test/data/rct-complete/completion_detect_rbtest2.taf b/Support/vendor/rcodetools/test/data/rct-complete/completion_detect_rbtest2.taf new file mode 100644 index 0000000..49eaf17 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/rct-complete/completion_detect_rbtest2.taf @@ -0,0 +1,9 @@ +========== +completion_detect_rbtest2 +========== +rct-complete --detect-rbtest --line=1 +========== +Array.new(3).uni +========== +uniq +uniq! diff --git a/Support/vendor/rcodetools/test/data/rct-complete/completion_emacs.taf b/Support/vendor/rcodetools/test/data/rct-complete/completion_emacs.taf new file mode 100644 index 0000000..9282ad0 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/rct-complete/completion_emacs.taf @@ -0,0 +1,13 @@ +========== +completion_emacs +========== +rct-complete --completion-emacs --line=1 +========== +Array.new(3).uni +========== +(progn +(setq rct-method-completion-table '(("uniq") ("uniq!") )) +(setq alist '(("uniq\t[Array#uniq]") ("uniq!\t[Array#uniq!]") )) +(setq pattern "uni") +(try-completion pattern rct-method-completion-table nil) +) diff --git a/Support/vendor/rcodetools/test/data/rct-complete/completion_emacs_icicles.taf b/Support/vendor/rcodetools/test/data/rct-complete/completion_emacs_icicles.taf new file mode 100644 index 0000000..324a1cf --- /dev/null +++ b/Support/vendor/rcodetools/test/data/rct-complete/completion_emacs_icicles.taf @@ -0,0 +1,13 @@ +========== +completion_emacs_icicles +========== +rct-complete --completion-emacs-icicles --line=1 +========== +1.div +========== +(progn +(setq rct-method-completion-table '(("div\t[Fixnum#div]") ("divmod\t[Fixnum#divmod]") )) +(setq alist '(("div" . "Fixnum#div")("divmod" . "Fixnum#divmod"))) +(setq pattern "div") +(setq klass "Fixnum") +) diff --git a/Support/vendor/rcodetools/test/data/rct-complete/completion_rbtest.taf b/Support/vendor/rcodetools/test/data/rct-complete/completion_rbtest.taf new file mode 100644 index 0000000..e8c6cbe --- /dev/null +++ b/Support/vendor/rcodetools/test/data/rct-complete/completion_rbtest.taf @@ -0,0 +1,15 @@ +========== +completion_rbtest +========== +rct-complete --rbtest --line=6 +========== +#!/usr/bin/env ruby +=begin test_bar +assert_equal "BAR", bar("bar") +=end +def bar(s) + s.upca +end +========== +upcase +upcase! diff --git a/Support/vendor/rcodetools/test/data/rct-doc/doc.taf b/Support/vendor/rcodetools/test/data/rct-doc/doc.taf new file mode 100644 index 0000000..aa017f6 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/rct-doc/doc.taf @@ -0,0 +1,8 @@ +========== +doc +========== +rct-doc -D --line=1 +========== +[].length +========== +Array#length diff --git a/Support/vendor/rcodetools/test/data/rct-doc/doc_detect_rbtest.taf b/Support/vendor/rcodetools/test/data/rct-doc/doc_detect_rbtest.taf new file mode 100644 index 0000000..28ac608 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/rct-doc/doc_detect_rbtest.taf @@ -0,0 +1,8 @@ +========== +doc_detect_rbtest +========== +rct-doc --detect-rbtest --line=1 +========== +[].length +========== +Array#length diff --git a/Support/vendor/rcodetools/test/data/rct-doc/doc_detect_rbtest2.taf b/Support/vendor/rcodetools/test/data/rct-doc/doc_detect_rbtest2.taf new file mode 100644 index 0000000..043bea9 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/rct-doc/doc_detect_rbtest2.taf @@ -0,0 +1,14 @@ +========== +doc_detect_rbtest2 +========== +rct-doc --detect-rbtest --line=6 +========== +#!/usr/bin/env ruby +=begin test_bar +assert_equal "BAR", bar("bar") +=end +def bar(s) + s.upcase +end +========== +String#upcase diff --git a/Support/vendor/rcodetools/test/data/rct-doc/doc_rbtest.taf b/Support/vendor/rcodetools/test/data/rct-doc/doc_rbtest.taf new file mode 100644 index 0000000..7da58ce --- /dev/null +++ b/Support/vendor/rcodetools/test/data/rct-doc/doc_rbtest.taf @@ -0,0 +1,14 @@ +========== +doc_rbtest +========== +rct-doc --rbtest --line=6 +========== +#!/usr/bin/env ruby +=begin test_bar +assert_equal "BAR", bar("bar") +=end +def bar(s) + s.upcase +end +========== +String#upcase diff --git a/Support/vendor/rcodetools/test/data/rct-doc/refe.taf b/Support/vendor/rcodetools/test/data/rct-doc/refe.taf new file mode 100644 index 0000000..6f07403 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/rct-doc/refe.taf @@ -0,0 +1,8 @@ +========== +refe +========== +rct-doc --refe --line=1 +========== +[].length +========== +refe 'Array#length' diff --git a/Support/vendor/rcodetools/test/data/rct-doc/ri.taf b/Support/vendor/rcodetools/test/data/rct-doc/ri.taf new file mode 100644 index 0000000..02f27d6 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/rct-doc/ri.taf @@ -0,0 +1,8 @@ +========== +ri +========== +rct-doc --ri --line=1 +========== +[].length +========== +ri 'Array#length' diff --git a/Support/vendor/rcodetools/test/data/rct-doc/ri_emacs.taf b/Support/vendor/rcodetools/test/data/rct-doc/ri_emacs.taf new file mode 100644 index 0000000..b41c7e3 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/rct-doc/ri_emacs.taf @@ -0,0 +1,8 @@ +========== +ri_emacs +========== +rct-doc --ri-emacs --line=1 +========== +[].length +========== +(rct-find-tag-or-ri "Array#length") diff --git a/Support/vendor/rcodetools/test/data/rct-doc/ri_vim.taf b/Support/vendor/rcodetools/test/data/rct-doc/ri_vim.taf new file mode 100644 index 0000000..11413ce --- /dev/null +++ b/Support/vendor/rcodetools/test/data/rct-doc/ri_vim.taf @@ -0,0 +1,8 @@ +========== +ri_vim +========== +rct-doc --ri-vim --line=1 +========== +[].length +========== +call RCT_find_tag_or_ri("Array#length") diff --git a/Support/vendor/rcodetools/test/data/sample_test_script.rb b/Support/vendor/rcodetools/test/data/sample_test_script.rb new file mode 100644 index 0000000..b368a8c --- /dev/null +++ b/Support/vendor/rcodetools/test/data/sample_test_script.rb @@ -0,0 +1,9 @@ +require 'test/unit' +class TestSample < Test::Unit::TestCase + def test_sample0 + assert(true) + end + + def test_sample1 + end +end diff --git a/Support/vendor/rcodetools/test/data/xmpfilter/add_markers.taf b/Support/vendor/rcodetools/test/data/xmpfilter/add_markers.taf new file mode 100644 index 0000000..88e8461 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/xmpfilter/add_markers.taf @@ -0,0 +1,10 @@ +========== +add_markers +========== +xmpfilter -m +========== +1+1 +2+3 +========== +1+1 # => +2+3 # => diff --git a/Support/vendor/rcodetools/test/data/xmpfilter/bindings.taf b/Support/vendor/rcodetools/test/data/xmpfilter/bindings.taf new file mode 100644 index 0000000..bcd3056 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/xmpfilter/bindings.taf @@ -0,0 +1,63 @@ +========== +bindings +========== +xmpfilter --poetry -u +========== + +require 'test/unit' + +class TestFoo < Test::Unit::TestCase + def setup + @o = [] + end + + def test_foo + a = 1 + b = a + b # => + end + + def test_arr + last = 1 + @o << last + @o.last # => + end + + def test_bar + a = b = c = 1 + d = a + d # => + end +end +========== + +require 'test/unit' + +class TestFoo < Test::Unit::TestCase + def setup + @o = [] + end + + def test_foo + a = 1 + b = a + assert_equal a, b + assert_equal 1, b + end + + def test_arr + last = 1 + @o << last + assert_equal last, @o.last + assert_equal 1, @o.last + end + + def test_bar + a = b = c = 1 + d = a + assert_equal a, d + assert_equal b, d + assert_equal c, d + assert_equal 1, d + end +end diff --git a/Support/vendor/rcodetools/test/data/xmpfilter/comment_out.taf b/Support/vendor/rcodetools/test/data/xmpfilter/comment_out.taf new file mode 100644 index 0000000..2520e79 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/xmpfilter/comment_out.taf @@ -0,0 +1,22 @@ +========== +comment_out +========== +xmpfilter +========== + +# 1 # => +# 1 # => 2 +1 # => 12 +1 +# # => +# 1 +# # => +========== + +# 1 # => +# 1 # => 2 +1 # => 1 +1 +# # => +# 1 +# # => diff --git a/Support/vendor/rcodetools/test/data/xmpfilter/exception.taf b/Support/vendor/rcodetools/test/data/xmpfilter/exception.taf new file mode 100644 index 0000000..3918c2e --- /dev/null +++ b/Support/vendor/rcodetools/test/data/xmpfilter/exception.taf @@ -0,0 +1,14 @@ +========== +exception +========== +xmpfilter +========== +def foo + raise NameError, "ERR!!" rescue $@ # => +end +foo +========== +def foo + raise NameError, "ERR!!" rescue $@ # => ["-:2:in `foo'", "-:4"] +end +foo diff --git a/Support/vendor/rcodetools/test/data/xmpfilter/expectations.taf b/Support/vendor/rcodetools/test/data/xmpfilter/expectations.taf new file mode 100644 index 0000000..ad244d7 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/xmpfilter/expectations.taf @@ -0,0 +1,54 @@ +========== +expectations +========== +xmpfilter --expectations +========== + +require 'rubygems' +require 'expectations' + +S = Struct.new :a +Expectations do + 1 + 1 # => + "a".length # => + [][1] # => + 1.hoge # => + 1.1 + 1.0 # => + S.new(1) # => +end +========== + +require 'rubygems' +require 'expectations' + +S = Struct.new :a +Expectations do + expect 2 do + 1 + 1 + end + + expect 1 do + "a".length + end + + expect nil do + [][1] + end + + expect NoMethodError do + 1.hoge + end + + expect 2.0999..2.1001 do + 1.1 + 1.0 + end + + expect S do + S.new(1) + end + + expect "#" do + S.new(1).inspect + end + +end diff --git a/Support/vendor/rcodetools/test/data/xmpfilter/last_match.taf b/Support/vendor/rcodetools/test/data/xmpfilter/last_match.taf new file mode 100644 index 0000000..56a0863 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/xmpfilter/last_match.taf @@ -0,0 +1,18 @@ +========== +last_match +========== +xmpfilter +========== + +md = "abc".match(/(.)(.)./) +1 +# => +[$1, $2] # => +$1 # => +========== + +md = "abc".match(/(.)(.)./) +1 +# => 1 +[$1, $2] # => ["a", "b"] +$1 # => "a" diff --git a/Support/vendor/rcodetools/test/data/xmpfilter/mult.rb b/Support/vendor/rcodetools/test/data/xmpfilter/mult.rb new file mode 100644 index 0000000..fa9025a --- /dev/null +++ b/Support/vendor/rcodetools/test/data/xmpfilter/mult.rb @@ -0,0 +1,9 @@ +a = ["1111111111111111111111111111111111111111111111111111", 123334324234242342, + 1332333333,6,8 ] +1 # => 1 +a +# => ["1111111111111111111111111111111111111111111111111111", +# 123334324234242342, +# 1332333333, +# 6, +# 8] diff --git a/Support/vendor/rcodetools/test/data/xmpfilter/multi_line_annotation_1.taf b/Support/vendor/rcodetools/test/data/xmpfilter/multi_line_annotation_1.taf new file mode 100644 index 0000000..63a0a05 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/xmpfilter/multi_line_annotation_1.taf @@ -0,0 +1,22 @@ +========== +multi_line_annotation_1 +========== +xmpfilter +========== + +1+2 # => +a = ["1111111111111111111111111111111111111111111111111111", 123334324234242342, + 1332333333 ] +1+2 # => +a +# => +========== + +1+2 # => 3 +a = ["1111111111111111111111111111111111111111111111111111", 123334324234242342, + 1332333333 ] +1+2 # => 3 +a +# => ["1111111111111111111111111111111111111111111111111111", +# 123334324234242342, +# 1332333333] diff --git a/Support/vendor/rcodetools/test/data/xmpfilter/multi_line_annotation_2.taf b/Support/vendor/rcodetools/test/data/xmpfilter/multi_line_annotation_2.taf new file mode 100644 index 0000000..d5027db --- /dev/null +++ b/Support/vendor/rcodetools/test/data/xmpfilter/multi_line_annotation_2.taf @@ -0,0 +1,24 @@ +========== +multi_line_annotation_2 +========== +xmpfilter +========== + +1+2 # => 32 +a = ["1111111111111111111111111111111111111111111111111111", 123334324234242342, + 55555555 ] +1+2 # => 300 +a +# => ["1111111111111111111111111111111111111111111111111111", +# 123334324234242342, +# 1332333333] +========== + +1+2 # => 3 +a = ["1111111111111111111111111111111111111111111111111111", 123334324234242342, + 55555555 ] +1+2 # => 3 +a +# => ["1111111111111111111111111111111111111111111111111111", +# 123334324234242342, +# 55555555] diff --git a/Support/vendor/rcodetools/test/data/xmpfilter/multi_line_annotation_3.taf b/Support/vendor/rcodetools/test/data/xmpfilter/multi_line_annotation_3.taf new file mode 100644 index 0000000..2b5efef --- /dev/null +++ b/Support/vendor/rcodetools/test/data/xmpfilter/multi_line_annotation_3.taf @@ -0,0 +1,20 @@ +========== +multi_line_annotation_3 +========== +xmpfilter +========== + +a = ["1111111111111111111111111111111111111111111111111111", 123334324234242342, + 1332333333 ] +a +# => +1 # => +========== + +a = ["1111111111111111111111111111111111111111111111111111", 123334324234242342, + 1332333333 ] +a +# => ["1111111111111111111111111111111111111111111111111111", +# 123334324234242342, +# 1332333333] +1 # => 1 diff --git a/Support/vendor/rcodetools/test/data/xmpfilter/multi_line_annotation_4.taf b/Support/vendor/rcodetools/test/data/xmpfilter/multi_line_annotation_4.taf new file mode 100644 index 0000000..e8adac7 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/xmpfilter/multi_line_annotation_4.taf @@ -0,0 +1,22 @@ +========== +multi_line_annotation_4 +========== +xmpfilter +========== + +a = ["1111111111111111111111111111111111111111111111111111", 123334324234242342, + 55555555 ] +a +# => ["1111111111111111111111111111111111111111111111111111", +# 123334324234242342, +# 1332333333] +# not removed +========== + +a = ["1111111111111111111111111111111111111111111111111111", 123334324234242342, + 55555555 ] +a +# => ["1111111111111111111111111111111111111111111111111111", +# 123334324234242342, +# 55555555] +# not removed diff --git a/Support/vendor/rcodetools/test/data/xmpfilter/multi_line_annotation_5.taf b/Support/vendor/rcodetools/test/data/xmpfilter/multi_line_annotation_5.taf new file mode 100644 index 0000000..af0cb84 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/xmpfilter/multi_line_annotation_5.taf @@ -0,0 +1,34 @@ +========== +multi_line_annotation_5 +========== +xmpfilter +========== + +def test + a = ["1111111111111111111111111111111111111111111111111111", 123334324234242342, + 55555555 ] + a + # => ["", + # 123334324234242342, + # 1332333333] + a + # => + # not removed +end +test +========== + +def test + a = ["1111111111111111111111111111111111111111111111111111", 123334324234242342, + 55555555 ] + a + # => ["1111111111111111111111111111111111111111111111111111", + # 123334324234242342, + # 55555555] + a + # => ["1111111111111111111111111111111111111111111111111111", + # 123334324234242342, + # 55555555] + # not removed +end +test diff --git a/Support/vendor/rcodetools/test/data/xmpfilter/multi_line_annotation_6.taf b/Support/vendor/rcodetools/test/data/xmpfilter/multi_line_annotation_6.taf new file mode 100644 index 0000000..24c48e2 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/xmpfilter/multi_line_annotation_6.taf @@ -0,0 +1,12 @@ +========== +multi_line_annotation_6 +========== +xmpfilter +========== + +1 + 2 # !> warning +# => +========== + +1 + 2 +# => 3 diff --git a/Support/vendor/rcodetools/test/data/xmpfilter/multi_line_annotation_7.taf b/Support/vendor/rcodetools/test/data/xmpfilter/multi_line_annotation_7.taf new file mode 100644 index 0000000..21ed1da --- /dev/null +++ b/Support/vendor/rcodetools/test/data/xmpfilter/multi_line_annotation_7.taf @@ -0,0 +1,23 @@ +========== +multi_line_annotation_7 +========== +xmpfilter +========== + +[1,2] +# => +raise +[3,4] +# => +[5,6] +# => +========== + +[1,2] +# => [1, 2] +raise +[3,4] +# => +[5,6] +# => +# ~> -:2: unhandled exception diff --git a/Support/vendor/rcodetools/test/data/xmpfilter/no_warnings.taf b/Support/vendor/rcodetools/test/data/xmpfilter/no_warnings.taf new file mode 100644 index 0000000..76cf8b0 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/xmpfilter/no_warnings.taf @@ -0,0 +1,13 @@ +========== +no_warnings +========== +xmpfilter --no-warnings +========== +A = 1 +A = 1 +p (1) +========== +A = 1 +A = 1 +p (1) +# >> 1 diff --git a/Support/vendor/rcodetools/test/data/xmpfilter/nospace.taf b/Support/vendor/rcodetools/test/data/xmpfilter/nospace.taf new file mode 100644 index 0000000..bb71aea --- /dev/null +++ b/Support/vendor/rcodetools/test/data/xmpfilter/nospace.taf @@ -0,0 +1,16 @@ +========== +nospace_annotation +========== +xmpfilter +========== + +1 #=> +2 #=> 2 +3 +#=> +========== + +1 # => 1 +2 # => 2 +3 +# => 3 diff --git a/Support/vendor/rcodetools/test/data/xmpfilter/rspec.taf b/Support/vendor/rcodetools/test/data/xmpfilter/rspec.taf new file mode 100644 index 0000000..6c3a3d6 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/xmpfilter/rspec.taf @@ -0,0 +1,106 @@ +========== +rspec +========== +xmpfilter -s +========== + +class X + Y = Struct.new(:a) + def foo(b); b ? Y.new(2) : 2 end + def bar; raise "No good" end + def baz; nil end + def fubar(x); x ** 2.0 + 1 end + def babar; [1,2] end + A = 1 + A = 1 +end + + +describe "xmpfilter's expectation expansion" do + before do + @o = X.new + end + + it "should expand should == expectations" do + @o.foo(true) # => + @o.foo(true).a # => + @o.foo(false) # => + end + + it "should expand should raise_error expectations" do + @o.bar # => + end + + it "should expand should be_nil expectations" do + @o.baz # => + end + + it "should expand correct expectations for complex values" do + @o.babar # => + end + + it "should expand should be_close expectations" do + @o.fubar(10) # => + end +end + +describe "xmpfilter's automagic binding detection" do + it "should expand should == expectations" do + a = b = c = 1 + d = a + d # => + end +end +========== + +class X + Y = Struct.new(:a) + def foo(b); b ? Y.new(2) : 2 end + def bar; raise "No good" end + def baz; nil end + def fubar(x); x ** 2.0 + 1 end + def babar; [1,2] end + A = 1 + A = 1 # !> already initialized constant A +end + + +describe "xmpfilter's expectation expansion" do + before do + @o = X.new + end + + it "should expand should == expectations" do + (@o.foo(true)).should be_a_kind_of(X::Y) + (@o.foo(true).inspect).should == ("#") + (@o.foo(true).a).should == (2) + (@o.foo(false)).should == (2) + end + + it "should expand should raise_error expectations" do + lambda{@o.bar}.should raise_error(RuntimeError) + end + + it "should expand should be_nil expectations" do + (@o.baz).should be_nil + end + + it "should expand correct expectations for complex values" do + (@o.babar).should == ([1, 2]) + end + + it "should expand should be_close expectations" do + (@o.fubar(10)).should be_close(101.0, 0.0001) + end +end + +describe "xmpfilter's automagic binding detection" do + it "should expand should == expectations" do + a = b = c = 1 + d = a + (d).should == (a) + (d).should == (b) + (d).should == (c) + (d).should == (1) + end +end diff --git a/Support/vendor/rcodetools/test/data/xmpfilter/rspec_poetry.taf b/Support/vendor/rcodetools/test/data/xmpfilter/rspec_poetry.taf new file mode 100644 index 0000000..0bcd685 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/xmpfilter/rspec_poetry.taf @@ -0,0 +1,106 @@ +========== +rspec_poetry +========== +xmpfilter -s --poetry +========== + +class X + Y = Struct.new(:a) + def foo(b); b ? Y.new(2) : 2 end + def bar; raise "No good" end + def baz; nil end + def fubar(x); x ** 2.0 + 1 end + def babar; [1,2] end + A = 1 + A = 1 +end + + +describe "xmpfilter's expectation expansion" do + before do + @o = X.new + end + + it "should expand should == expectations" do + @o.foo(true) # => + @o.foo(true).a # => + @o.foo(false) # => + end + + it "should expand should raise_error expectations" do + @o.bar # => + end + + it "should expand should be_nil expectations" do + @o.baz # => + end + + it "should expand correct expectations for complex values" do + @o.babar # => + end + + it "should expand should be_close expectations" do + @o.fubar(10) # => + end +end + +describe "xmpfilter's automagic binding detection" do + it "should expand should == expectations" do + a = b = c = 1 + d = a + d # => + end +end +========== + +class X + Y = Struct.new(:a) + def foo(b); b ? Y.new(2) : 2 end + def bar; raise "No good" end + def baz; nil end + def fubar(x); x ** 2.0 + 1 end + def babar; [1,2] end + A = 1 + A = 1 # !> already initialized constant A +end + + +describe "xmpfilter's expectation expansion" do + before do + @o = X.new + end + + it "should expand should == expectations" do + @o.foo(true).should be_a_kind_of(X::Y) + @o.foo(true).inspect.should == "#" + @o.foo(true).a.should == 2 + @o.foo(false).should == 2 + end + + it "should expand should raise_error expectations" do + lambda{@o.bar}.should raise_error(RuntimeError) + end + + it "should expand should be_nil expectations" do + @o.baz.should be_nil + end + + it "should expand correct expectations for complex values" do + @o.babar.should == [1, 2] + end + + it "should expand should be_close expectations" do + @o.fubar(10).should be_close(101.0, 0.0001) + end +end + +describe "xmpfilter's automagic binding detection" do + it "should expand should == expectations" do + a = b = c = 1 + d = a + d.should == a + d.should == b + d.should == c + d.should == 1 + end +end diff --git a/Support/vendor/rcodetools/test/data/xmpfilter/simple_annotation.taf b/Support/vendor/rcodetools/test/data/xmpfilter/simple_annotation.taf new file mode 100644 index 0000000..9aa82d5 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/xmpfilter/simple_annotation.taf @@ -0,0 +1,22 @@ +========== +simple_annotation +========== +xmpfilter +========== + +a = 1 +10.times do |i| + i ** 2 # => + a += i +end +A = 1 +A = 1 +========== + +a = 1 +10.times do |i| + i ** 2 # => 0, 1, 4, 9, 16, 25, 36, 49, 64, 81 + a += i +end +A = 1 +A = 1 # !> already initialized constant A diff --git a/Support/vendor/rcodetools/test/data/xmpfilter/unit_test.taf b/Support/vendor/rcodetools/test/data/xmpfilter/unit_test.taf new file mode 100644 index 0000000..662ae86 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/xmpfilter/unit_test.taf @@ -0,0 +1,108 @@ +========== +unit_test +========== +xmpfilter -u +========== + +class X + Y = Struct.new(:a) + def foo(b); b ? Y.new(2) : 2 end + def bar; raise "No good" end + def baz; nil end + def fubar(x); x ** 2.0 + 1 end + def babar; [1,2] end + A = 1 + A = 1 + def difftype() [1, "s"] end +end + + +require 'test/unit' +class Test_X < Test::Unit::TestCase + def setup + @o = X.new + end + + def test_foo + @o.foo(true) # => + @o.foo(true).a # => + @o.foo(false) # => + end + + def test_bar + @o.bar # => + end + + def test_baz + @o.baz # => + end + + def test_babar + @o.babar # => + end + + def test_fubar + @o.fubar(10) # => + end + + def test_difftype + for x in @o.difftype + x # => + end + end + +end + +========== + +class X + Y = Struct.new(:a) + def foo(b); b ? Y.new(2) : 2 end + def bar; raise "No good" end + def baz; nil end + def fubar(x); x ** 2.0 + 1 end + def babar; [1,2] end + A = 1 + A = 1 # !> already initialized constant A + def difftype() [1, "s"] end +end + + +require 'test/unit' +class Test_X < Test::Unit::TestCase + def setup + @o = X.new + end + + def test_foo + assert_kind_of(X::Y, @o.foo(true)) + assert_equal("#", @o.foo(true).inspect) + assert_equal(2, @o.foo(true).a) + assert_equal(2, @o.foo(false)) + end + + def test_bar + assert_raise(RuntimeError){@o.bar} + end + + def test_baz + assert_nil(@o.baz) + end + + def test_babar + assert_equal([1, 2], @o.babar) + end + + def test_fubar + assert_in_delta(101.0, @o.fubar(10), 0.0001) + end + + def test_difftype + for x in @o.difftype + #xmpfilter: WARNING!! extra values ignored + assert_equal(1, x) + end + end + +end + diff --git a/Support/vendor/rcodetools/test/data/xmpfilter/unit_test_detect_rbtest.taf b/Support/vendor/rcodetools/test/data/xmpfilter/unit_test_detect_rbtest.taf new file mode 100644 index 0000000..7cc5893 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/xmpfilter/unit_test_detect_rbtest.taf @@ -0,0 +1,108 @@ +========== +unit_test_detect_rbtest +========== +xmpfilter -u --detect-rbtest +========== + +class X + Y = Struct.new(:a) + def foo(b); b ? Y.new(2) : 2 end + def bar; raise "No good" end + def baz; nil end + def fubar(x); x ** 2.0 + 1 end + def babar; [1,2] end + A = 1 + A = 1 + def difftype() [1, "s"] end +end + + +require 'test/unit' +class Test_X < Test::Unit::TestCase + def setup + @o = X.new + end + + def test_foo + @o.foo(true) # => + @o.foo(true).a # => + @o.foo(false) # => + end + + def test_bar + @o.bar # => + end + + def test_baz + @o.baz # => + end + + def test_babar + @o.babar # => + end + + def test_fubar + @o.fubar(10) # => + end + + def test_difftype + for x in @o.difftype + x # => + end + end + +end + +========== + +class X + Y = Struct.new(:a) + def foo(b); b ? Y.new(2) : 2 end + def bar; raise "No good" end + def baz; nil end + def fubar(x); x ** 2.0 + 1 end + def babar; [1,2] end + A = 1 + A = 1 # !> already initialized constant A + def difftype() [1, "s"] end +end + + +require 'test/unit' +class Test_X < Test::Unit::TestCase + def setup + @o = X.new + end + + def test_foo + assert_kind_of(X::Y, @o.foo(true)) + assert_equal("#", @o.foo(true).inspect) + assert_equal(2, @o.foo(true).a) + assert_equal(2, @o.foo(false)) + end + + def test_bar + assert_raise(RuntimeError){@o.bar} + end + + def test_baz + assert_nil(@o.baz) + end + + def test_babar + assert_equal([1, 2], @o.babar) + end + + def test_fubar + assert_in_delta(101.0, @o.fubar(10), 0.0001) + end + + def test_difftype + for x in @o.difftype + #xmpfilter: WARNING!! extra values ignored + assert_equal(1, x) + end + end + +end + diff --git a/Support/vendor/rcodetools/test/data/xmpfilter/unit_test_detect_rbtest2.taf b/Support/vendor/rcodetools/test/data/xmpfilter/unit_test_detect_rbtest2.taf new file mode 100644 index 0000000..219b4a9 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/xmpfilter/unit_test_detect_rbtest2.taf @@ -0,0 +1,18 @@ +========== +unit_test_detect_rbtest2 +========== +xmpfilter --detect-rbtest +========== +=begin test_bar +bar("bar") # => +=end +def bar(s) + s.upcase +end +========== +=begin test_bar +assert_equal("BAR", bar("bar")) +=end +def bar(s) + s.upcase +end diff --git a/Support/vendor/rcodetools/test/data/xmpfilter/unit_test_poetry.taf b/Support/vendor/rcodetools/test/data/xmpfilter/unit_test_poetry.taf new file mode 100644 index 0000000..b7c2490 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/xmpfilter/unit_test_poetry.taf @@ -0,0 +1,108 @@ +========== +unit_test_poetry +========== +xmpfilter -u --poetry +========== + +class X + Y = Struct.new(:a) + def foo(b); b ? Y.new(2) : 2 end + def bar; raise "No good" end + def baz; nil end + def fubar(x); x ** 2.0 + 1 end + def babar; [1,2] end + A = 1 + A = 1 + def difftype() [1, "s"] end +end + + +require 'test/unit' +class Test_X < Test::Unit::TestCase + def setup + @o = X.new + end + + def test_foo + @o.foo(true) # => + @o.foo(true).a # => + @o.foo(false) # => + end + + def test_bar + @o.bar # => + end + + def test_baz + @o.baz # => + end + + def test_babar + @o.babar # => + end + + def test_fubar + @o.fubar(10) # => + end + + def test_difftype + for x in @o.difftype + x # => + end + end + +end + +========== + +class X + Y = Struct.new(:a) + def foo(b); b ? Y.new(2) : 2 end + def bar; raise "No good" end + def baz; nil end + def fubar(x); x ** 2.0 + 1 end + def babar; [1,2] end + A = 1 + A = 1 # !> already initialized constant A + def difftype() [1, "s"] end +end + + +require 'test/unit' +class Test_X < Test::Unit::TestCase + def setup + @o = X.new + end + + def test_foo + assert_kind_of X::Y, @o.foo(true) + assert_equal "#", @o.foo(true).inspect + assert_equal 2, @o.foo(true).a + assert_equal 2, @o.foo(false) + end + + def test_bar + assert_raise(RuntimeError){@o.bar} + end + + def test_baz + assert_nil @o.baz + end + + def test_babar + assert_equal [1, 2], @o.babar + end + + def test_fubar + assert_in_delta 101.0, @o.fubar(10), 0.0001 + end + + def test_difftype + for x in @o.difftype + #xmpfilter: WARNING!! extra values ignored + assert_equal 1, x + end + end + +end + diff --git a/Support/vendor/rcodetools/test/data/xmpfilter/unit_test_rbtest.taf b/Support/vendor/rcodetools/test/data/xmpfilter/unit_test_rbtest.taf new file mode 100644 index 0000000..622f118 --- /dev/null +++ b/Support/vendor/rcodetools/test/data/xmpfilter/unit_test_rbtest.taf @@ -0,0 +1,18 @@ +========== +unit_test_rbtest +========== +xmpfilter -u --rbtest +========== +=begin test_bar +bar("bar") # => +=end +def bar(s) + s.upcase +end +========== +=begin test_bar +assert_equal("BAR", bar("bar")) +=end +def bar(s) + s.upcase +end diff --git a/Support/vendor/rcodetools/test/data/xmpfilter/width.taf b/Support/vendor/rcodetools/test/data/xmpfilter/width.taf new file mode 100644 index 0000000..4fa436e --- /dev/null +++ b/Support/vendor/rcodetools/test/data/xmpfilter/width.taf @@ -0,0 +1,16 @@ +========== +width +========== +xmpfilter -w 15 +========== + +a = ["abcdefg", 12345, Object] +a +# => +========== + +a = ["abcdefg", 12345, Object] +a +# => ["abcdefg", +# 12345, +# Object] diff --git a/Support/vendor/rcodetools/test/test_completion.rb b/Support/vendor/rcodetools/test/test_completion.rb index 54d87ec..fce0fef 100644 --- a/Support/vendor/rcodetools/test/test_completion.rb +++ b/Support/vendor/rcodetools/test/test_completion.rb @@ -3,6 +3,7 @@ require 'test/unit' class TestXMPCompletionFilter < Test::Unit::TestCase + include Rcodetools def doit(code, lineno, column=nil, options={}) xmp = XMPCompletionFilter.new options xmp.candidates(code, lineno, column).sort @@ -29,12 +30,13 @@ def hoge end def test_complete_method__in_not_passing_method - ## FIXME I do not know how to handle not-passing method!! - assert_equal([], doit(<true)) + assert_raises(XMPCompletionFilter::NoCandidates) do + doit(code, 3, nil, :ignore_NoMethodError=>true) + end end def test__syntax_error @@ -496,6 +519,7 @@ def test_class__NotClass class TestXMPCompletionVerboseFilter < Test::Unit::TestCase + include Rcodetools def doit(code, lineno, column=nil, options={}) xmp = XMPCompletionVerboseFilter.new options xmp.candidates(code, lineno, column).sort @@ -515,6 +539,16 @@ def test_complete_instance_variable EOC end + def test_complete_list_instance_variable + assert_equal(%w[@bar @baz @foo @hoge], doit(< [], :unit_test => ["-u"], :rspec => ["-s"], - :no_warnings => ["--no-warnings"], :bindings => ["--poetry", "-u"], - :add_markers => ["-m"] - } - tests.each_pair do |test, opts| - define_method("test_#{test}") do - dir = File.expand_path(File.dirname(__FILE__)) - libdir = File.expand_path(dir + '/../lib') - exec = File.expand_path(dir + '/../bin/xmpfilter') - output = `ruby -I#{libdir} #{exec} #{opts.join(" ")} #{dir}/data/#{test}-input.rb` - outputfile = "#{dir}/data/#{test}-output.rb" - assert_equal(File.read(outputfile), output) + def self.parse_taf(filename) + open(filename) do |io| + delimiter=Regexp.union(io.gets) + io.read.split(delimiter) end - end + end + + def tempfile_with_contents(contents) + input = Tempfile.new("rct-test") + input.write(contents) + input.close + input.path + end + + DIR = File.expand_path(File.dirname(__FILE__)) + LIBDIR = File.expand_path(DIR + '/../lib') + BINDIR = File.expand_path(DIR + '/../bin') + + # rct-complete-TDC + %w[xmpfilter rct-complete rct-doc].each do |subdir| + Dir["#{DIR}/data/#{subdir}/*.taf"].each do |taf| + desc, cmdline, input, output = parse_taf(taf) + [desc, cmdline].each{|x| x.chomp! } + define_method("test_#{desc}") do + inputfile = tempfile_with_contents(input) + actual_output = `ruby -I#{LIBDIR} #{BINDIR}/#{cmdline} #{inputfile}` + assert_equal output, actual_output + end + end + end + + # TODO + Dir["#{DIR}/data/rct-complete-TDC/*.taf"].each do |taf| + desc, cmdline, input, output, test = parse_taf(taf) + [desc, cmdline].each{|x| x.chomp! } + define_method("test_#{desc}") do + inputfile = tempfile_with_contents(input) + testfile = tempfile_with_contents(test) + actual_output = `ruby -I#{LIBDIR} #{BINDIR}/#{cmdline % [inputfile, testfile]} #{inputfile}` + assert_equal output, actual_output + end + end + end diff --git a/Support/vendor/rcodetools/test/test_method_analyzer.rb b/Support/vendor/rcodetools/test/test_method_analyzer.rb index f40d69b..7ad36c2 100644 --- a/Support/vendor/rcodetools/test/test_method_analyzer.rb +++ b/Support/vendor/rcodetools/test/test_method_analyzer.rb @@ -9,7 +9,7 @@ module ScriptConfig class MethodAnalyzerTextOutput < Test::Unit::TestCase include ScriptConfig -# test (find-sh "ruby -r../method_analyzer data/method_analyzer-data.rb") + # test (find-sh "ruby -r../method_analyzer data/method_analyzer-data.rb") # attr_accessor is actually Module#attr_accessor. # But `f?ri Module.attr_accessor' answers correctly. @@ -68,17 +68,6 @@ class MethodAnalyzerMarshalOutput < Test::Unit::TestCase METHOD_ANALYSIS = File.join(DIR, "method_analysis") at_exit { File.unlink METHOD_ANALYSIS rescue nil} - def setup - ENV['METHOD_ANALYZER_FORMAT'] = 'marshal' - @pwd = Dir.pwd - Dir.chdir DIR - end - - def teardown - ENV['METHOD_ANALYZER_FORMAT'] = nil - Dir.chdir @pwd - end - def write_temp_file(str, file) file.replace File.expand_path(file) at_exit { File.unlink file } @@ -86,14 +75,33 @@ def write_temp_file(str, file) end def test_marshal_merged - a = write_temp_file "z=1+2", "mergeA.rb" - b = write_temp_file "[].empty?", "mergeB.rb" - - system "ruby -r#{SCRIPT} mergeA.rb" - system "ruby -r#{SCRIPT} mergeB.rb" + begin + ENV['METHOD_ANALYZER_FORMAT'] = 'marshal' + @pwd = Dir.pwd + Dir.chdir DIR + a = write_temp_file "z=1+2", "mergeA.rb" + system "ruby -r#{SCRIPT} mergeA.rb" + method_analysis = Marshal.load(File.read(METHOD_ANALYSIS)) + assert_equal ["Fixnum#+"], method_analysis[File.join(DIR, "mergeA.rb")][1] + ensure + ENV.delete 'METHOD_ANALYZER_FORMAT' + Dir.chdir @pwd + end + end - method_analysis = Marshal.load(File.read(METHOD_ANALYSIS)) - assert_equal ["Fixnum#+"], method_analysis[File.join(DIR, "mergeA.rb")][1] - assert_equal ["Array#empty?"], method_analysis[File.join(DIR, "mergeB.rb")][1] + def test_marshal_merged + begin + ENV['METHOD_ANALYZER_FORMAT'] = 'marshal' + @pwd = Dir.pwd + Dir.chdir DIR + + b = write_temp_file "[].empty?", "mergeB.rb" + system "ruby -r#{SCRIPT} mergeB.rb" + method_analysis = Marshal.load(File.read(METHOD_ANALYSIS)) + assert_equal ["Array#empty?"], method_analysis[File.join(DIR, "mergeB.rb")][1] + ensure + ENV.delete 'METHOD_ANALYZER_FORMAT' + Dir.chdir @pwd + end end end diff --git a/Support/vendor/rcodetools/test/test_options.rb b/Support/vendor/rcodetools/test/test_options.rb index 33a2020..8751516 100644 --- a/Support/vendor/rcodetools/test/test_options.rb +++ b/Support/vendor/rcodetools/test/test_options.rb @@ -5,6 +5,7 @@ require 'fileutils' class TestOptionHandler < Test::Unit::TestCase + include Rcodetools include OptionHandler def include_paths_check diff --git a/Support/vendor/rcodetools/test/test_ruby_toggle_file.rb b/Support/vendor/rcodetools/test/test_ruby_toggle_file.rb new file mode 100644 index 0000000..e7960f9 --- /dev/null +++ b/Support/vendor/rcodetools/test/test_ruby_toggle_file.rb @@ -0,0 +1,174 @@ +require 'fileutils' +require 'test/unit' +require 'ruby_toggle_file' +require 'tmpdir' + +class TestRubyToggleFile < Test::Unit::TestCase + WORK_DIR = "#{Dir.tmpdir}/zdsfwfwejiotest".freeze + FileUtils.rm_rf WORK_DIR + + def teardown + FileUtils.rm_rf WORK_DIR + end + + def create(*files) + for file in files.map{|f| _(f) } + FileUtils.mkpath(File.dirname(file)) + open(file,"w"){} + end + end + + def _(path) # make full path + WORK_DIR + "/" + path + end + + ########################################################################### + # naming convention # + # test_METHOD__EXISTP__IMPLEMENTDIR_TESTDIR # + ########################################################################### + def test_test_file__exist__lib_test + create "lib/zero.rb", "test/test_zero.rb" + rtf = RubyToggleFile.new + assert_equal _("test/test_zero.rb"), rtf.ruby_toggle_file(_("lib/zero.rb")) + end + + def test_test_file__exist__libone_testone + create "lib/one/one.rb", "test/one/test_one.rb" + rtf = RubyToggleFile.new + assert_equal _("test/one/test_one.rb"), rtf.ruby_toggle_file(_("lib/one/one.rb")) + end + + def test_test_file__exist__libtwo_test + create "lib/two/two.rb", "test/test_two.rb" + rtf = RubyToggleFile.new + assert_equal _("test/test_two.rb"), rtf.ruby_toggle_file(_("lib/two/two.rb")) + end + + def test_test_file__exist__top_test + create "three.rb", "test_three.rb" + rtf = RubyToggleFile.new + assert_equal _("test_three.rb"), rtf.ruby_toggle_file(_("three.rb")) + end + + def test_test_file__not_exist__top + create "four.rb" + rtf = RubyToggleFile.new + assert_equal _("test_four.rb"), rtf.ruby_toggle_file(_("four.rb")) + end + + def test_test_file__not_exist__lib + create "lib/five.rb" + rtf = RubyToggleFile.new + assert_equal _("test/test_five.rb"), rtf.ruby_toggle_file(_("lib/five.rb")) + end + + def test_test_file__not_exist__libsixsix + create "lib/six/six/six.rb" + rtf = RubyToggleFile.new + assert_equal _("test/six/six/test_six.rb"), rtf.ruby_toggle_file(_("lib/six/six/six.rb")) + end + + def test_implementation_file__exist__lib_test + create "lib/zero.rb", "test/test_zero.rb" + rtf = RubyToggleFile.new + assert_equal _("lib/zero.rb"), rtf.ruby_toggle_file(_("test/test_zero.rb")) + end + + def test_implementation_file__exist__libone_testone + create "lib/one/one.rb", "test/one/test_one.rb" + rtf = RubyToggleFile.new + assert_equal _("lib/one/one.rb"), rtf.ruby_toggle_file(_("test/one/test_one.rb")) + end + + def test_implementation_file__exist__libtwo_test + create "lib/two/two.rb", "test/test_two.rb" + rtf = RubyToggleFile.new + assert_equal _("lib/two/two.rb"), rtf.ruby_toggle_file(_("test/test_two.rb")) + end + + def test_implementation_file__exist__top_test + create "three.rb", "test_three.rb" + rtf = RubyToggleFile.new + assert_equal _("three.rb"), rtf.ruby_toggle_file(_("test_three.rb")) + end + + def test_implementation_file__not_exist__none_top + create "test_seven.rb" + rtf = RubyToggleFile.new + assert_equal _("seven.rb"), rtf.ruby_toggle_file(_("test_seven.rb")) + end + + def test_implementation_file__not_exist__none_test + create "test/test_eight.rb" + rtf = RubyToggleFile.new + assert_equal _("lib/eight.rb"), rtf.ruby_toggle_file(_("test/test_eight.rb")) + end + + def test_implementation_file__not_exist__none_testninenine + create "test/nine/nine/nine.rb" + rtf = RubyToggleFile.new + assert_equal _("lib/nine/nine/nine.rb"), rtf.ruby_toggle_file(_("test/nine/nine/test_nine.rb")) + end + + ########################################################################### + # Rails test # + ########################################################################### + def test_test_file__rails_controllers + create "app/controllers/c.rb", "test/functional/c_test.rb" + rtf = RubyToggleFile.new + assert_equal _("test/functional/c_test.rb"), rtf.ruby_toggle_file(_("app/controllers/c.rb")) + end + + def test_test_file__rails_models + create "app/models/m.rb", "test/unit/m_test.rb" + rtf = RubyToggleFile.new + assert_equal _("test/unit/m_test.rb"), rtf.ruby_toggle_file(_("app/models/m.rb")) + end + + def test_test_file__rails_lib + create "lib/l.rb", "test/unit/test_l.rb", "app/models/m.rb" + rtf = RubyToggleFile.new + assert_equal _("test/unit/test_l.rb"), rtf.ruby_toggle_file(_("lib/l.rb")) + end + + + def test_implementation_file__rails_controllers + create "app/controllers/c.rb", "test/functional/c_test.rb" + rtf = RubyToggleFile.new + assert_equal _("app/controllers/c.rb"), rtf.ruby_toggle_file(_("test/functional/c_test.rb")) + end + + def test_implementation_file__rails_models + create "app/models/m.rb", "test/unit/m_test.rb" + rtf = RubyToggleFile.new + assert_equal _("app/models/m.rb"), rtf.ruby_toggle_file(_("test/unit/m_test.rb")) + end + + def test_implementation_file__rails_lib + create "lib/l.rb", "test/unit/test_l.rb", "app/models/m.rb" + rtf = RubyToggleFile.new + assert_equal _("lib/l.rb"), rtf.ruby_toggle_file(_("test/unit/test_l.rb")) + end +end + + +class TestRunHooksWithArgsUntilSuccess < Test::Unit::TestCase + def m001(x) nil end + private + def m002(x) false end + def m003(x) 100*x end + def m004(x) 200 end + + public + def test_run_hooks_with_args_until_success__m003 + assert_equal 1000, run_hooks_with_args_until_success(/^m\d+$/, 10) + end + + def test_run_hooks_with_args_until_success__m001 + assert_nil run_hooks_with_args_until_success(/^m001$/, 10) + end + + def test_run_hooks_with_args_until_success__m004 + assert_equal 200, run_hooks_with_args_until_success(/^m004$/, 10) + end +end diff --git a/Support/vendor/rcodetools/test/test_xmpfilter.rb b/Support/vendor/rcodetools/test/test_xmpfilter.rb index 95ca5e6..154361b 100644 --- a/Support/vendor/rcodetools/test/test_xmpfilter.rb +++ b/Support/vendor/rcodetools/test/test_xmpfilter.rb @@ -1,36 +1,191 @@ require 'test/unit' -$: << ".." << "../lib[s]" +$: << ".." << "../lib" require "rcodetools/xmpfilter" +require 'rubygems' +require 'mocha' class TestXMPFilter < Test::Unit::TestCase - def setup - @xmp = XMPFilter.new - @marker = XMPFilter::MARKER + include Rcodetools + def test_extract_data__results + marker = XMPFilter::MARKER + str = <<-EOF +#{marker}[1] => Fixnum 42 +#{marker}[1] => Fixnum 0 +#{marker}[1] ==> var +#{marker}[1] ==> var2 +#{marker}[4] ==> var3 +#{marker}[2] ~> some exception +#{marker}[10] => Fixnum 42 + EOF + xmp = XMPFilter.new + data = xmp.extract_data(str) + assert_equal([[1, [["Fixnum", "42"], ["Fixnum", "0"]]], [10, [["Fixnum", "42"]]]], data.results.sort) end - def test_extract_data + def test_extract_data__exceptions + marker = XMPFilter::MARKER str = <<-EOF -#{@marker}[1] => Fixnum 42 -#{@marker}[1] => Fixnum 0 -#{@marker}[1] ==> var -#{@marker}[1] ==> var2 -#{@marker}[4] ==> var3 -#{@marker}[2] ~> some exception -#{@marker}[10] => Fixnum 42 +#{marker}[1] => Fixnum 42 +#{marker}[1] => Fixnum 0 +#{marker}[1] ==> var +#{marker}[1] ==> var2 +#{marker}[4] ==> var3 +#{marker}[2] ~> some exception +#{marker}[10] => Fixnum 42 EOF - data = @xmp.extract_data(str) - assert_kind_of(XMPFilter::RuntimeData, data) - assert_equal([[1, [["Fixnum", "42"], ["Fixnum", "0"]]], [10, [["Fixnum", "42"]]]], data.results.sort) + xmp = XMPFilter.new + data = xmp.extract_data(str) assert_equal([[2, ["some exception"]]], data.exceptions.sort) + end + + def test_extract_data__bindings + marker = XMPFilter::MARKER + str = <<-EOF +#{marker}[1] => Fixnum 42 +#{marker}[1] => Fixnum 0 +#{marker}[1] ==> var +#{marker}[1] ==> var2 +#{marker}[4] ==> var3 +#{marker}[2] ~> some exception +#{marker}[10] => Fixnum 42 + EOF + xmp = XMPFilter.new + data = xmp.extract_data(str) assert_equal([[1, ["var", "var2"]], [4, ["var3"]]], data.bindings.sort) end -end -class TestXMPAddMarkers < Test::Unit::TestCase + def test_interpreter_command + xmp = XMPFilter.new(:interpreter=>"ruby", :detect_rct_fork => false) + assert_equal(%w[ruby -w], xmp.interpreter_command) + end + + def test_interpreter_command_detect_rct_fork + Fork.stubs(:run?).returns true + xmp = XMPFilter.new(:interpreter=>"ruby", :detect_rct_fork => true) + assert_equal(%w[ruby -S rct-fork-client], xmp.interpreter_command) + end + + def test_interpreter_command_use_rbtest + xmp = XMPFilter.new(:interpreter=>"ruby", :use_rbtest => true) + assert_equal(%w[ruby -S rbtest], xmp.interpreter_command) + end + + def test_initialize__test_script_1 + XMPFilter.any_instance.stubs(:safe_require_code).returns("require 'test/unit'") + xmp = XMPFilter.new(:test_script=>"/path/to/test/test_ruby_toggle_file.rb", + :test_method=>"test_implementation_file_file_exist", + :filename=>"/path/to/lib/ruby_toggle_file.rb") + + evals_expected = [ + %q!$LOADED_FEATURES << "ruby_toggle_file.rb"!, + %q!require 'test/unit'!, + %q!load "/path/to/test/test_ruby_toggle_file.rb"!, + %q!Test::Unit::AutoRunner.run(false, nil, ["-n", "test_implementation_file_file_exist"])! + ] + assert_equal evals_expected, xmp.instance_variable_get(:@evals) + end + + def test_initialize__test_script_2 + XMPFilter.any_instance.stubs(:safe_require_code).returns("require 'test/unit'") + xmp = XMPFilter.new(:test_script=>"/path/to/test_ruby_toggle_file.rb", + :test_method=>"test_implementation_file_file_exist", + :filename=>"/path/to/ruby_toggle_file.rb") + + evals_expected = [ + %q!$LOADED_FEATURES << "ruby_toggle_file.rb"!, + %q!require 'test/unit'!, + %q!load "/path/to/test_ruby_toggle_file.rb"!, + %q!Test::Unit::AutoRunner.run(false, nil, ["-n", "test_implementation_file_file_exist"])! + ] + assert_equal evals_expected, xmp.instance_variable_get(:@evals) + end + + def test_initialize__test_script_3 + test_script = File.join(File.dirname(__FILE__), "data/sample_test_script.rb") + filename = File.join(File.dirname(__FILE__), "data/sample.rb") + XMPFilter.any_instance.stubs(:safe_require_code).returns("require 'test/unit'") + xmp = XMPFilter.new(:test_script=>test_script, :test_method=>"4", :filename=>filename) + + evals_expected = [ + %q!$LOADED_FEATURES << "sample.rb"!, + %q!require 'test/unit'!, + %Q!load #{test_script.dump}!, + %q!Test::Unit::AutoRunner.run(false, nil, ["-n", "test_sample0"])! + ] + assert_equal evals_expected, xmp.instance_variable_get(:@evals) + end + + def test_initialize__test_script__filename_eq_test_script + test_script = File.join(File.dirname(__FILE__), "data/sample_test_script.rb") + filename = test_script + xmp = XMPFilter.new(:test_script=>test_script, :test_method=>"4", :filename=>filename) + + evals_expected = [ + %q!Test::Unit::AutoRunner.run(false, nil, ["-n", "test_sample0"])! + ] + assert_equal evals_expected, xmp.instance_variable_get(:@evals) + end + + def test_get_test_method_from_lineno + file = File.join(File.dirname(__FILE__), "data/sample_test_script.rb") + xmp = XMPFilter.new + assert_equal("test_sample0", xmp.get_test_method_from_lineno(file, 4)) + assert_equal("test_sample1", xmp.get_test_method_from_lineno(file, 7)) + assert_equal("test_sample1", xmp.get_test_method_from_lineno(file, 8)) + assert_equal(nil, xmp.get_test_method_from_lineno(file, 1)) + end + + # Use methods to avoid confusing syntax highlighting + def beg() "=begin" end + def ed() "=end" end + def test_s_detect_rbtest_1 + rbtest_script_1 = < true} + assert_equal true, XMPFilter.detect_rbtest(rbtest_script_1, opts) + assert_equal true, opts[:use_rbtest] + opts = {:detect_rbtest => false} + assert_equal false, XMPFilter.detect_rbtest(rbtest_script_1, opts) + assert_equal false, opts[:use_rbtest] + opts = {:detect_rbtest => false, :use_rbtest => true} + assert_equal true, XMPFilter.detect_rbtest(rbtest_script_1, opts) + assert_equal true, opts[:use_rbtest] + end - def test_ + def test_s_detect_rbtest_2 + rbtest_script_2 = < true} + assert_equal true, XMPFilter.detect_rbtest(rbtest_script_2, opts) + assert_equal true, opts[:use_rbtest] + opts = {:detect_rbtest => false} + assert_equal false, XMPFilter.detect_rbtest(rbtest_script_2, opts) + assert_equal false, opts[:use_rbtest] + end + + def test_s_detect_rbtest_3 + no_rbtest_script = < true} + assert_equal false, XMPFilter.detect_rbtest(no_rbtest_script, opts) + assert_equal false, opts[:use_rbtest] + opts = {:detect_rbtest => false} + assert_equal false, XMPFilter.detect_rbtest(no_rbtest_script, opts) + assert_equal false, opts[:use_rbtest] end + end + diff --git a/Support/vendor/rcodetools/test/test_xmptestunitfilter.rb b/Support/vendor/rcodetools/test/test_xmptestunitfilter.rb index adadc82..d744e49 100644 --- a/Support/vendor/rcodetools/test/test_xmptestunitfilter.rb +++ b/Support/vendor/rcodetools/test/test_xmptestunitfilter.rb @@ -4,9 +4,7 @@ require "rcodetools/xmptestunitfilter" class TestXMPTestUnitFilter < Test::Unit::TestCase - def setup - @xmp = XMPTestUnitFilter.new - end + include Rcodetools ANNOTATION_VAR_INFERENCE_INPUT = <")) + xmp = XMPTestUnitFilter.new + assert_equal(["a = 1\n", "assert_equal(1, a)"], xmp.annotate("a = 1\na # \=>")) assert_equal(["a = {1,2}\n", "assert_equal({1=>2}, a)"], - @xmp.annotate("a = {1,2}\na # \=>")) + xmp.annotate("a = {1,2}\na # \=>")) assert_equal(["a = [1,2]\n", "assert_equal([1, 2], a)"], - @xmp.annotate("a = [1,2]\na # \=>")) + xmp.annotate("a = [1,2]\na # \=>")) assert_equal(["a = 'foo'\n", "assert_equal(\"foo\", a)"], - @xmp.annotate("a = 'foo'\na # \=>")) + xmp.annotate("a = 'foo'\na # \=>")) assert_equal(["a = 1.0\n", "assert_in_delta(1.0, a, 0.0001)"], - @xmp.annotate("a = 1.0\na # \=>")) + xmp.annotate("a = 1.0\na # \=>")) end def test_raise_assertion @@ -51,12 +51,14 @@ def test_raise_assertion class NoGood < Exception; end raise NoGood # \=> EOF + xmp = XMPTestUnitFilter.new assert_equal(["class NoGood < Exception; end\n", - "assert_raise(NoGood){raise NoGood}\n"], @xmp.annotate(code)) + "assert_raise(NoGood){raise NoGood}\n"], xmp.annotate(code)) end def test_assert_nil - assert_equal(["a = nil\n", "assert_nil(a)"], @xmp.annotate("a = nil\na # \=>")) + xmp = XMPTestUnitFilter.new + assert_equal(["a = nil\n", "assert_nil(a)"], xmp.annotate("a = nil\na # \=>")) end def test_poetry_mode diff --git a/Support/vendor/rcodetools/test/tmp_functional.rb b/Support/vendor/rcodetools/test/tmp_functional.rb new file mode 100644 index 0000000..339fdfc --- /dev/null +++ b/Support/vendor/rcodetools/test/tmp_functional.rb @@ -0,0 +1,162 @@ +require 'test/unit' + +module TestFunctional + DIR = File.expand_path(File.dirname(__FILE__)) + LIBDIR = File.expand_path(DIR + '/../lib') + + module DefineFunctionalTests + def define_functional_tests(bin, exec, tests) + tests.each_pair do |test, opts| + define_method("test_#{test}") do + + output = `ruby -I#{LIBDIR} #{exec} #{opts.join(" ")} #{DIR}/data/#{test}-input.rb` + outputfile = "#{DIR}/data/#{test}-output.rb" + taffile = "#{DIR}/data/#{bin}/#{test}.taf" + open(taffile, "w") do |f| + f.puts "==========" + f.puts test + f.puts "==========" + f.puts bin + " " + opts.join(" ") + f.puts "==========" + f.puts File.read("#{DIR}/data/#{test}-input.rb") + f.puts "==========" + f.puts File.read("#{DIR}/data/#{test}-output.rb") + end +# assert_equal(File.read(outputfile), output) + end + end + end + end + + class TestXmpfilter < Test::Unit::TestCase + extend DefineFunctionalTests + tests = { + :simple_annotation => [], :unit_test => ["-u"], :rspec => ["-s"], + :no_warnings => ["--no-warnings"], :bindings => ["--poetry", "-u"], + :add_markers => ["-m"], :unit_test_rbtest => ["-u", "--rbtest"], + :unit_test_detect_rbtest => ["-u", "--detect-rbtest"], + :unit_test_detect_rbtest2 => ["--detect-rbtest"], + } + define_functional_tests "xmpfilter", File.expand_path(DIR + '/../bin/xmpfilter'), tests + end + + class TestRctComplete < Test::Unit::TestCase + extend DefineFunctionalTests + tests = { + :completion_rbtest => [ "--rbtest", "--line=6" ], + :completion_detect_rbtest => [ "--detect-rbtest", "--line=6" ], + :completion_detect_rbtest2 => [ "--detect-rbtest", "--line=1" ], + } + define_functional_tests "rct-complete", File.expand_path(DIR + '/../bin/rct-complete'), tests + end + + class TestRctDoc < Test::Unit::TestCase + extend DefineFunctionalTests + tests = { + :doc_rbtest => [ "--rbtest", "--line=6" ], + :doc_detect_rbtest => [ "--detect-rbtest", "--line=1" ], + :doc_detect_rbtest2 => [ "--detect-rbtest", "--line=6" ], + } + define_functional_tests "rct-doc", File.expand_path(DIR + '/../bin/rct-doc'), tests + end + + + # Other tests are in test_run.rb + class TestRctCompleteTDC < Test::Unit::TestCase + test = :completion_in_method + inputfile = "#{DIR}/data/#{test}-input.rb" + outputfile = "#{DIR}/data/#{test}-output.rb" + test_script = "#{DIR}/data/#{test}-test.rb" + common_opts = ["--filename #{inputfile}", "--line 2"] + right_output = File.read(outputfile) + wrong_output = "\n" + + tests = { + :completion_in_method__testscript => + [ common_opts + ["-t #{test_script}"], right_output ], + :completion_in_method__testmethod => + [ common_opts + ["-t #{test_script}@test_fooz"], right_output ], + :completion_in_method__wrong_testmethod => + [ common_opts + ["-t #{test_script}@test_NOT_FOUND"], wrong_output ], + } + exec = File.expand_path(DIR + '/../bin/rct-complete') +# tests.each_pair do |test, (opts, expected)| +# define_method("test_#{test}") do +# output = `ruby -I#{LIBDIR} #{exec} #{opts.join(" ")} #{inputfile}` + +# taffile = "#{DIR}/data/#{bin}/#{test}.taf" +# open(taffile, "w") do |f| +# f.puts "==========" +# f.puts test +# f.puts "==========" +# f.puts bin + " " + opts.join(" ") +# f.puts "==========" +# f.puts File.read("#{DIR}/data/#{test}-input.rb") +# f.puts "==========" +# f.puts File.read("#{DIR}/data/#{test}-output.rb") +# end +# end +# end + + test=:completion_in_method__testscript + define_method("test_#{test}") do + taffile = "#{DIR}/data/rct-complete-TDC/completion_in_method__testscript.taf" + open(taffile, "w") do |f| + opts = tests[test] + f.puts "==========" + f.puts test + f.puts "==========" + f.puts "rct-complete " + opts.join(" ") + f.puts "==========" + test0 = :completion_in_method + f.puts File.read("#{DIR}/data/#{test0}-input.rb") + f.puts "==========" + f.puts File.read("#{DIR}/data/#{test0}-output.rb") + f.puts "==========" + f.puts File.read("#{DIR}/data/#{test0}-test.rb") + end + + end + + test=:completion_in_method__testmethod + define_method("test_#{test}") do + taffile = "#{DIR}/data/rct-complete-TDC/completion_in_method__testmethod.taf" + open(taffile, "w") do |f| + opts = tests[test] + f.puts "==========" + f.puts test + f.puts "==========" + f.puts "rct-complete " + opts.join(" ") + f.puts "==========" + test0 = :completion_in_method + f.puts File.read("#{DIR}/data/#{test0}-input.rb") + f.puts "==========" + f.puts File.read("#{DIR}/data/#{test0}-output.rb") + f.puts "==========" + f.puts File.read("#{DIR}/data/#{test0}-test.rb") + end + + end + + test=:completion_in_method__wrong_testmethod + define_method("test_#{test}") do + taffile = "#{DIR}/data/rct-complete-TDC/completion_in_method__wrong_testmethod.taf" + open(taffile, "w") do |f| + opts = tests[test] + f.puts "==========" + f.puts test + f.puts "==========" + f.puts "rct-complete " + opts.join(" ") + f.puts "==========" + test0 = :completion_in_method + f.puts File.read("#{DIR}/data/#{test0}-input.rb") + f.puts "==========" + f.puts + f.puts "==========" + f.puts File.read("#{DIR}/data/#{test0}-test.rb") + end + + end + + end +end diff --git a/Support/vendor/rcodetools/test/tmp_run.rb b/Support/vendor/rcodetools/test/tmp_run.rb new file mode 100644 index 0000000..b3bed0d --- /dev/null +++ b/Support/vendor/rcodetools/test/tmp_run.rb @@ -0,0 +1,66 @@ +require 'test/unit' +require 'rcodetools/xmpfilter' +require 'rcodetools/xmptestunitfilter' +require 'rcodetools/completion' +require 'rcodetools/doc' +require 'rcodetools/options' +require 'stringio' + +class TestRun < Test::Unit::TestCase + include Rcodetools + DIR = File.expand_path(File.dirname(__FILE__)) + + tests = { +# :rspec_poetry => {:klass => XMPRSpecFilter, :interpreter => "spec", :use_parentheses => false}, + :rspec_poetry => ["xmpfilter", "-s --poetry"], +# :unit_test_poetry => {:klass => XMPTestUnitFilter, :use_parentheses => false}, + :unit_test_poetry => ["xmpfilter", "-u --poetry"], + +# :completion => {:klass => XMPCompletionFilter, :lineno => 1}, + :completion => ["rct-complete", "-C --line=1"], +# :completion_emacs => {:klass => XMPCompletionEmacsFilter, :lineno => 1}, + :completion_emacs => ["rct-complete", "--completion-emacs --line=1"], +# :completion_emacs_icicles => {:klass => XMPCompletionEmacsIciclesFilter, :lineno => 1}, + :completion_emacs_icicles => ["rct-complete","--completion-emacs-icicles --line=1"], +# :completion_class_info => {:klass => XMPCompletionClassInfoFilter, :lineno => 1}, + :completion_class_info => ["rct-complete", "--completion-class-info --line=1"], +# :completion_class_info_no_candidates => {:klass => XMPCompletionClassInfoFilter, :lineno => 1}, + :completion_class_info_no_candidates => ["rct-complete", "--completion-class-info --line=1"], + +# :doc => {:klass => XMPDocFilter, :lineno => 1}, +# :refe => {:klass => XMPReFeFilter, :lineno => 1}, +# :ri => {:klass => XMPRiFilter, :lineno => 1}, +# :ri_emacs => {:klass => XMPRiEmacsFilter, :lineno => 1}, +# :ri_vim => {:klass => XMPRiVimFilter, :lineno => 1}, + :doc => ["rct-doc", "-D --line=1"], + :refe => ["rct-doc", "--refe --line=1"], + :ri => ["rct-doc", "--ri --line=1"], + :ri_emacs => ["rct-doc", "--ri-emacs --line=1"], + :ri_vim => ["rct-doc", "--ri-vim --line=1"], + + } + DIR = File.expand_path(File.dirname(__FILE__)) + LIBDIR = File.expand_path(DIR + '/../lib') + + tests.each_pair do |test, (bin,opts)| + define_method("test_#{test}") do + inputfile = "#{DIR}/data/#{test}-input.rb" + outputfile = "#{DIR}/data/#{test}-output.rb" + +# exec = File.expand_path(DIR + '/../bin/xmpfilter') +# output = `ruby -I#{LIBDIR} #{exec} #{opts} #{DIR}/data/#{test}-input.rb` +# outputfile = "#{DIR}/data/#{test}-output.rb" + taffile = "#{DIR}/data/#{bin}/#{test}.taf" + open(taffile, "w") do |f| + f.puts "==========" + f.puts test + f.puts "==========" + f.puts bin + " " + opts + f.puts "==========" + f.puts File.read("#{DIR}/data/#{test}-input.rb") + f.puts "==========" + f.puts File.read("#{DIR}/data/#{test}-output.rb") + end + end + end +end