├── CHANGES ├── README ├── README.TDC ├── README.emacs ├── README.ja ├── README.method_analysis ├── README.vim ├── README.xmpfilter ├── Rakefile ├── Rakefile.method_analysis ├── THANKS ├── anything-rcodetools.el ├── bin ├── rbtest ├── rct-complete ├── rct-doc ├── rct-fork ├── rct-fork-client ├── rct-meth-args ├── ruby-toggle-file └── xmpfilter ├── icicles-rcodetools.el ├── lib ├── method_analyzer.rb ├── rcodetools │ ├── compat.rb │ ├── completion.rb │ ├── doc.rb │ ├── fork.rb │ ├── fork_config.rb │ ├── options.rb │ ├── xmpfilter.rb │ └── xmptestunitfilter.rb └── ruby_toggle_file.rb ├── rcodetools.el ├── rcodetools.elc ├── rcodetools.gif ├── rcodetools.sxmp ├── rcodetools.vim ├── setup.rb └── test ├── attic └── test_run.rb ├── data ├── attic │ ├── add_markers-input.rb │ ├── add_markers-output.rb │ ├── bindings-input.rb │ ├── bindings-output.rb │ ├── completion-input.rb │ ├── completion-output.rb │ ├── completion_class_info-input.rb │ ├── completion_class_info-output.rb │ ├── completion_class_info_no_candidates-input.rb │ ├── completion_class_info_no_candidates-output.rb │ ├── completion_detect_rbtest-input.rb │ ├── completion_detect_rbtest-output.rb │ ├── completion_detect_rbtest2-input.rb │ ├── completion_detect_rbtest2-output.rb │ ├── completion_emacs-input.rb │ ├── completion_emacs-output.rb │ ├── completion_emacs_icicles-input.rb │ ├── completion_emacs_icicles-output.rb │ ├── completion_in_method-input.rb │ ├── completion_in_method-output.rb │ ├── completion_in_method-test.rb │ ├── completion_rbtest-input.rb │ ├── completion_rbtest-output.rb │ ├── doc-input.rb │ ├── doc-output.rb │ ├── doc_detect_rbtest-input.rb │ ├── doc_detect_rbtest-output.rb │ ├── doc_detect_rbtest2-input.rb │ ├── doc_detect_rbtest2-output.rb │ ├── doc_rbtest-input.rb │ ├── doc_rbtest-output.rb │ ├── no_warnings-input.rb │ ├── no_warnings-output.rb │ ├── refe-input.rb │ ├── refe-output.rb │ ├── ri-input.rb │ ├── ri-output.rb │ ├── ri_emacs-input.rb │ ├── ri_emacs-output.rb │ ├── ri_vim-input.rb │ ├── ri_vim-output.rb │ ├── rspec-input.rb │ ├── rspec-output.rb │ ├── rspec_poetry-input.rb │ ├── rspec_poetry-output.rb │ ├── simple_annotation-input.rb │ ├── simple_annotation-output.rb │ ├── unit_test-input.rb │ ├── unit_test-output.rb │ ├── unit_test_detect_rbtest-input.rb │ ├── unit_test_detect_rbtest-output.rb │ ├── unit_test_detect_rbtest2-input.rb │ ├── unit_test_detect_rbtest2-output.rb │ ├── unit_test_poetry-input.rb │ ├── unit_test_poetry-output.rb │ ├── unit_test_rbtest-input.rb │ └── unit_test_rbtest-output.rb ├── method_analyzer-data.rb ├── method_args.data.rb ├── rct-complete-TDC │ ├── completion_in_method__testmethod.taf │ ├── completion_in_method__testscript.taf │ └── completion_in_method__wrong_testmethod.taf ├── rct-complete │ ├── completion.taf │ ├── completion_class_info.taf │ ├── completion_class_info_no_candidates.taf │ ├── completion_detect_rbtest.taf │ ├── completion_detect_rbtest2.taf │ ├── completion_emacs.taf │ ├── completion_emacs_icicles.taf │ └── completion_rbtest.taf ├── rct-doc │ ├── doc.taf │ ├── doc_detect_rbtest.taf │ ├── doc_detect_rbtest2.taf │ ├── doc_rbtest.taf │ ├── refe.taf │ ├── ri.taf │ ├── ri_emacs.taf │ └── ri_vim.taf ├── sample_test_script.rb └── xmpfilter │ ├── add_markers.taf │ ├── bindings.taf │ ├── comment_out.taf │ ├── exception.taf │ ├── expectations.taf │ ├── last_match.taf │ ├── mult.rb │ ├── multi_line_annotation_1.taf │ ├── multi_line_annotation_2.taf │ ├── multi_line_annotation_3.taf │ ├── multi_line_annotation_4.taf │ ├── multi_line_annotation_5.taf │ ├── multi_line_annotation_6.taf │ ├── multi_line_annotation_7.taf │ ├── no_warnings.taf │ ├── nospace.taf │ ├── rspec.taf │ ├── rspec_poetry.taf │ ├── simple_annotation.taf │ ├── unit_test.taf │ ├── unit_test_detect_rbtest.taf │ ├── unit_test_detect_rbtest2.taf │ ├── unit_test_poetry.taf │ ├── unit_test_rbtest.taf │ └── width.taf ├── test_completion.rb ├── test_doc.rb ├── test_functional.rb ├── test_method_analyzer.rb ├── test_method_args.rb ├── test_options.rb ├── test_ruby_toggle_file.rb ├── test_xmpfilter.rb ├── test_xmptestunitfilter.rb ├── tmp_functional.rb └── tmp_run.rb /CHANGES: -------------------------------------------------------------------------------- 1 | rcodetools history 2 | ================== 3 | User-visible changes since 0.8.4 4 | -------------------------------- 5 | * OOPS, added missing files. 6 | 7 | User-visible changes since 0.8.0 8 | -------------------------------- 9 | * xmpfilter: fixed multi-line annotation bugs 10 | 11 | User-visible changes since 0.7.0 12 | -------------------------------- 13 | * Support Ruby 1.9! 14 | * xmpfilter: multi-line annotation 15 | * xmpfilter --expectations generates expectations by Jay Fields 16 | * anything-rcodetools.el: new elisp 17 | * --tmpfile, --tempfile: use temporary file instead of open3 on un*x 18 | * rcodetools.el: smarter xmpfilter-command 19 | * rcodetools.el: rct-fork interface 20 | * rct-fork: require 'rubygems' initially 21 | * rct-fork: more stable 22 | 23 | User-visible changes since 0.5.0 24 | -------------------------------- 25 | * "test-driven completion" (TDC) support for Emacs and vim (see README.TDC) 26 | * --test (-t), --filename options for rct-complete and rct-doc, allowing to 27 | specify the test to be run for 100% accurate completion/documentation in the 28 | corresponding implementation 29 | * ruby-toggle-file: finds the test file corresponding to a given 30 | implementation and vice versa 31 | * rct-fork, rct-fork-client: allow to eliminate the overhead due to library 32 | loading (esp. useful for Rails) 33 | * rbtest: executes unit tests in a single Ruby script 34 | * --fork, --rbtest, --detect-rbtest supported by several commands 35 | * xmpfilter's --spec now autodetects the RSpec version and generates 36 | specifications with the appropriate syntax 37 | 38 | User-visible changes since 0.4.1 39 | -------------------------------- 40 | * --dev: adds project directories to $: 41 | * --completion-class-info: list completion candidates and class info 42 | * display completion candidates with description, both in emacs 43 | and vim (using the menu+preview window). 44 | 45 | User-visible changes since 0.4.0 46 | -------------------------------- 47 | * rct-meth-args: implemented -I 48 | * many bug fixes 49 | 50 | xmpfilter was integrated into rcodetools as of 0.4.0. 51 | 52 | xmpfilter history 53 | ================= 54 | User-visible changes since 0.3.1 (2006-10-17) 55 | * implemented --debug 56 | * --[no]-warnings 57 | * --cd working_dir 58 | * --rails 59 | * --no-poetry 60 | * more intelligent assertions: try to find which local variables hold the 61 | values compared against in assertions/expectations 62 | * editor-independent completion (-C, --completion-emacs, --completion-vim) 63 | * quick method/class reference with -D (--refe, --ri*) 64 | 65 | User-visible changes since 0.3.0 (2006-10-16) 66 | * xmpfilter.rb --spec works on win32 too 67 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | = This repo 2 | 3 | I did not write rcodetools, nor do I maintain it. 4 | The gem does not list an official repository, 5 | and its website is down. I am purely hosting a version 6 | of what is installed from `gem unpack rcodetools`, 7 | so that I have a repository that I can reference back to. 8 | 9 | This is version 0.8.5.0, 10 | the changes I have made are only this change to the readme. 11 | 12 | If you like rcodetool's xmpfilter, I maintain 13 | SeeingIsBelieving[https://github.com/JoshCheek/seeing_is_believing#readme] 14 | a tool intended to succeed it. 15 | 16 | = Copyright info 17 | 18 | rcodetools http://eigenclass.org/hiki.rb?rcodetools 19 | Copyright (c) 2005-2007 Mauricio Fernandez http://eigenclass.org 20 | Copyright (c) 2006-2008 rubikitch http://www.rubyist.net/~rubikitch/ 21 | Use and distribution subject to the terms of the Ruby license. 22 | 23 | = Overview 24 | rcodetools is a collection of Ruby code manipulation tools. 25 | It includes xmpfilter and editor-independent Ruby development helper tools, 26 | as well as emacs and vim interfaces. 27 | 28 | Currently, rcodetools comprises: 29 | * xmpfilter: Automagic Test::Unit assertions/RSpec expectations and code annotations 30 | * rct-complete: Accurate method/class/constant etc. completions 31 | * rct-doc: Document browsing and code navigator 32 | * rct-meth-args: Precise method info (meta-prog. aware) and TAGS generation 33 | * rct-fork: Pre-load heavy library(Rails etc) and speed up rct-complete/rct-doc (server) 34 | * rct-fork-client: Run Ruby programs from state the rct-fork server has 35 | * ruby-toggle-file: Toggle implementation file and test file 36 | * rbtest: Embedded Test::Unit for small scripts 37 | 38 | See also README.xmpfilter. 39 | 40 | Originally rct-complete and rct-doc were subcommands of xmpfilter. 41 | Actually they use xmpfilter's code heavily. 42 | But the relationship between xmpfilter (annotation) and completion/doc is not 43 | intuitive, so I (rubikitch) split it into separate executables. 44 | 45 | = Usage 46 | xmpfilter, rct-complete and rct-doc take its input from stdin and write to 47 | stdout. They can run in several modes; see 48 | xmpfilter -h 49 | rct-complete -h 50 | rct-doc -h 51 | rct-meth-args -h 52 | rct-fork -h 53 | rct-fork-client -h 54 | ruby-toggle-file -h 55 | rbtest -h 56 | README.emacs and README.vim describe how to use rcodetools from your editor. 57 | 58 | = Accurate Completion Internal and Caveat 59 | rct-complete and rct-doc use xmpfilter engine, ie they get runtime information by executing code. 60 | In Ruby (dynamic languages), type of any expressions except literals cannot be known without actually executing code. 61 | Moreover Ruby has open classes and singleton methods. 62 | Rcodetools asks `ruby' run-time informations, so we can get very accurate informations. 63 | Completion and document browsing are essentially identical operations, 64 | they both need the object value in question. 65 | Therefore we discuss completion. 66 | 67 | rct-complete does: 68 | (1) replaces target line with completion magic 69 | (it calculates methods the target object has). 70 | (2) executes modified script. 71 | (3) once the control reaches completion magic, modified script exits. 72 | (4) outputs in specified format. (list candidates, EmacsLisp...) 73 | 74 | But this methodology has two big drawbacks, side-effects and inability to get any informations of uncovered code! 75 | 76 | An extreme side-effect example: 77 | File.unlink a_file 78 | File. <- 79 | 80 | If you call rct-complete, it removes a_file (sends a mail, accesses DB ...). 81 | So you must be careful to use, especially at TOPLEVEL. 82 | I (rubikitch) often experiment at TOPLEVEL with rcodetools, I NEVER use irb(sh) since rcodetools! 83 | 84 | An uncovered code example: 85 | def foo 86 | 1. <- 87 | end 88 | 89 | If the code does not call foo, we cannot do any completions. 90 | 91 | Useless eh? But we already have a way to elude the drawbacks, test scripts (unit tests)! 92 | Test scripts are self-enclosed and expected to be executed, so side-effects are not problem. 93 | Moreover tests call methods we write. 94 | Because Ruby's Test::Unit has an ability to test only one test method, we can do lightning-fast completion. 95 | Let's call it Test-Driven Completion (TDC). 96 | 97 | To support TDC, rct-complete has -t option. 98 | With -t, it concatenate modified script and test/unit code. 99 | If the control does not reach target line, test/unit code calls the line. 100 | 101 | How do we select test script and test method? 102 | The editor selects recently selected buffer of test script as test script of TDC, 103 | because the test-infected tend to go and return between test script and implementation script. 104 | It considers files matching /test.*\.rb/ as test script. 105 | It selects test method at the cursor position. 106 | 107 | TDC adds roles of test scripts. 108 | Enjoy TDC magic! 109 | 110 | See also README.TDC. 111 | 112 | 113 | = License 114 | rcodetools is licensed under the same terms as Ruby. 115 | -------------------------------------------------------------------------------- /README.TDC: -------------------------------------------------------------------------------- 1 | 2 | = Overview 3 | 4 | Ruby is very dynamic language, therefore it is impossible to do 5 | accurate completion without executing script. While executing script 6 | from start to cursor point is often dangerous, executing unit test 7 | script covering current point is SAFE. I call this methodology 8 | `Test-Driven Completion' (TDC). 9 | 10 | As I have already stated in README, browsing documentation of method 11 | (rct-doc) is almost identical operation to completion. This 12 | discussion is applicable to rct-doc. 13 | 14 | = Why TDD Is Needed 15 | 16 | In the following code snippet: 17 | 18 | File.unlink a_file 19 | File. <- 20 | 21 | If you complete after `File.', rct-complete actually deletes a_file. 22 | Normally it is unpleasant. 23 | In real-life development, side-effect is inevitable. 24 | 25 | In the foo method which are not called: 26 | 27 | def foo 28 | 1. <- 29 | end 30 | 31 | If the code does not call foo, rct-complete cannot do any completions. 32 | Before TDC, if you want to do completion in methods, you have to write 33 | method call and remove it after completion. Too useless!! 34 | 35 | = Messianic Unit Test Script 36 | 37 | Recently Test-Driven Development (TDD) is widespread. Many developers 38 | write unit tests. Fortunately Ruby's unit tester, Test::Unit, is 39 | sophisticated enough to test one test method. Unit tests are 40 | self-enclosed: they must tear down resources, so executing unit tests 41 | are SAFE. TDC uses unit test to do completion. 42 | 43 | = TDC Methodology 44 | 45 | (1) Switch to unit test script. 46 | (2) Write a test for target method. 47 | (3) Switch to implementation script. 48 | (4) You can write target method WITH COMPLETION! 49 | (5) Back to (1) 50 | 51 | TDC methodology is almost identical to TDD. TDC is very easy for TDDers. 52 | 53 | = TDC With Example 54 | 55 | For simplicity, suppose that you are unfamiliar with Time class and 56 | you want to write a method to format date string. 57 | 58 | The directory structure and file contents is following: 59 | 60 | /tmp/mylib0/ 61 | /tmp/mylib0/lib/ 62 | mylib0.rb 63 | /tmp/mylib0/test/ 64 | test_mylib0.rb 65 | 66 | List: mylib0.rb 67 | # contrived example of long-runtime method 68 | def mysleep(x) 69 | sleep x 70 | end 71 | 72 | def mytime(tm) 73 | 74 | end 75 | 76 | 77 | List: test_mylib0.rb 78 | require 'test/unit' 79 | require 'mylib0' 80 | class TestMylib0 < Test::Unit::TestCase 81 | def test_0_mysleep 82 | s = Time.now 83 | mysleep 3.0 84 | e = Time.now 85 | assert_in_delta 3.0, e-s, 0.01 86 | end 87 | 88 | def test_1_mytime 89 | 90 | end 91 | end 92 | 93 | These sample files are in demo/ directory. 94 | 95 | 96 | == Switch to unit test script. 97 | 98 | TDC starts with writing unit test as TDD does. 99 | Open test_mylib0.rb. 100 | 101 | == Write a test for target method. 102 | 103 | Suppose that you want to write mytime method and test_1_mytime test 104 | method, and that you want to experiment Time class first (before 105 | forming an assertion). 106 | 107 | In TDC, you do not have to write an assertion first: just write only a 108 | method call. If you are familiar with Time class, you are free to 109 | write an assertion, of course. 110 | 111 | def test_1_mytime 112 | mytime(Time.now) 113 | end 114 | 115 | At this time, the cursor position is in test_1_mytime test method. 116 | 117 | == Switch to implementation script. 118 | 119 | Open mylib0.rb with the `ruby-toggle-file' script. For example, in Emacs use 120 | the `ruby-toggle-buffer' command, and in vim the t (by default 121 | \t) binding. Since in TDD/TDC you often switch between the test and the 122 | implementation, it is much handier than typing the filename manually. 123 | 124 | The rct-complete uses latest-selected test script as TDC test script 125 | and test method at cursor position as TDC test method. In this case, 126 | test_mylib0.rb is TDC test script and test_1_mytime is TDC test 127 | method. If the cursor position of test_mylib0.rb is at the top, 128 | rct-complete executes whole test methods in test_mylib0.rb. Therefore 129 | latency of completion is longer. 130 | 131 | == You can write target method WITH COMPLETION! 132 | 133 | Fill mytime method. 134 | 135 | def mytime(tm) 136 | tm. 137 | end 138 | 139 | Do completion after `tm.'. Here! Your editor is listing methods `tm' 140 | accepts!! If your editor has help-on-candidate mechanism (eg. Emacs + 141 | Icicles), you would see documentation of each listed method. 142 | 143 | Then you find `Time#strftime' method. Type `str' and do completion. 144 | 145 | def mytime(tm) 146 | tm.strftime 147 | end 148 | 149 | Usage is... use `rct-doc' (in Emacs, `rct-ri') after `strftime'. 150 | 151 | After you are familiar with Time class, switch to test script and write assertions. 152 | 153 | = When Modifying Another Method 154 | 155 | If you want to modify already-written method, setting cursor position 156 | of corresponding test script to corresponding test method is better. 157 | It tells rct-complete new test script and test method, so you can do 158 | completion in the new method. 159 | -------------------------------------------------------------------------------- /README.emacs: -------------------------------------------------------------------------------- 1 | 2 | rcodetools.el allows you to run rcodetools on a buffer. 3 | 4 | To eval the sexp, type C-e C-x C-e; `end-of-line' and `eval-last-sexp'. 5 | 6 | installation 7 | ============ 8 | 9 | If you use RI document feature, you must install ri-emacs first. 10 | http://rubyforge.org/projects/ri-emacs/ 11 | 12 | If you feel RI and ri-emacs.rb startup is SLOW, you want to install FastRI. 13 | FastRI offers ri-emacs compatible layer, so you can use it with ri-ruby.el. 14 | http://eigenclass.org/hiki.rb?fastri 15 | 16 | Copy rcodetools.el to the appropriate directory, which is in load-path. 17 | Then require it. 18 | (require 'rcodetools) 19 | 20 | If you use icicles copy icicles-rcodetools.el too. 21 | Then require it. 22 | (require 'icicles-rcodetools) 23 | It provides wonderful `help on candidate' feature, RI document on each candidate during completion. 24 | 25 | If you use anything.el copy anything-rcodetools.el too. 26 | Then require it. 27 | (require 'anything-rcodetools) 28 | RI document on each candidate during completion. 29 | 30 | anything-show-completion.el shows selection (mehod) in buffer for completion. 31 | It is available in: 32 | http://www.emacswiki.org/cgi-bin/wiki/download/anything-show-completion.el 33 | 34 | I think anything-rcodetools is more convenient than icicles-rcodetools. 35 | I'm addicted to anything! 36 | http://www.emacswiki.org/cgi-bin/wiki/Anything 37 | 38 | xmpfilter on buffer 39 | =================== 40 | 41 | # [EVAL IT] (describe-function 'xmp) 42 | 43 | If you want to add => marks, call comment-dwim twice. 44 | 45 | # [EVAL IT] (describe-function 'comment-dwim) 46 | 47 | method/class/constant completion 48 | ================================ 49 | 50 | # [EVAL IT] (describe-function 'rct-complete-symbol) 51 | 52 | If you use icicles-rcodetools or anything-rcodetools, you can browse RI document 53 | for selected candidate by typing C-M-RET (icicles) or C-z (anything. 54 | It is wonderful icicles and anything feature!! 55 | 56 | show RI document / jump to the definition 57 | ========================================= 58 | 59 | # [EVAL IT] (describe-function 'rct-ri) 60 | 61 | By default rct-ri asks for a TAGS file, which is generated by tag generator like rtags. 62 | If there is a TAGS file, this command jumps to the definition of current method. 63 | If use do not use this feature, evaluate: 64 | (setq rct-find-tag-if-available nil) 65 | 66 | # [EVAL IT] (describe-variable 'rct-find-tag-if-available) 67 | 68 | speed-up xmpfilter and completion 69 | ================================= 70 | 71 | # [EVAL IT] (describe-function 'rct-fork) 72 | # [EVAL IT] (describe-function 'rct-fork-kill) 73 | 74 | M-x rct-fork pre-loads heavy libraries (like rails). 75 | You need not every time wait for loading them anymore! 76 | -------------------------------------------------------------------------------- /README.ja: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JoshCheek/rcodetools/0d0c448fe3bf3f2b2a51d89a2ff387e0c1c7da7c/README.ja -------------------------------------------------------------------------------- /README.method_analysis: -------------------------------------------------------------------------------- 1 | 2 | method_analyzer.rb can be used to gather precise information about the exact 3 | methods called in your code, allowing you to explore it better with rct-doc 4 | (see README.emacs and README.vim for more information). This requires high 5 | code coverage, since it can only record such data when the code is executed. 6 | 7 | rct-meth-args can be used to generate fairly complete TAGS files. It operates 8 | by loading the specified files and tracking method definitions; therefore, it 9 | is meta-programming aware, unlike other implementations. 10 | 11 | You can use them conveniently by adding the code shown in 12 | Rakefile.method_analysis to your Rakefile. 13 | 14 | -------------------------------------------------------------------------------- /README.vim: -------------------------------------------------------------------------------- 1 | 2 | Copy rcodetools.vim to your plugin directory (typically $HOME/.vim/plugin) in 3 | order to enable accurate code completion, quick RI execution and exact tag 4 | jumping. 5 | 6 | Switching between implementation and test files 7 | =============================================== 8 | The t binding (by default \t) will call ruby-toggle-file to 9 | switch from test to implementation and vice versa. Moreover, when you switch 10 | from the test to the implementation, rcodetools will remember which test 11 | you were editing (based on the cursor position), and call it as needed for 12 | advanced code completion or precise RI documentation, as documented below. 13 | 14 | The actual binding can be changed in your .vimrc as follows: 15 | let g:RCT_toggle_binding="" " use ^X^T to go test <=> implementation 16 | 17 | Code completion 18 | =============== 19 | rcodetools.vim redefines user-defined completion for Ruby programs, so you can 20 | use the intelligent, 100%-accurate completion with in insert mode. 21 | Note that this runs the code to obtain the exact candidate list. 22 | 23 | If you've set completeopt to menu,preview then rcodetools.vim can display 24 | information about the completion candidates. The menu will show the synopsis 25 | as given in the RI documentation, and the preview window will contain the full 26 | RI documentation. 27 | 28 | This functionality relies on fri for quick lookups. It can be enabled by setting 29 | 30 | let g:rct_completion_use_fri = 1 " 0 by default (disabled) 31 | 32 | in your .vimrc (don't forget to run fastri-server too). 33 | Obtaining the documentation for many candidates can be slow, so you can set 34 | the threshold above which additional documentation will not be shown with 35 | 36 | " 20 by default, about a couple secs max wait on a normal machine 37 | let g:rct_completion_info_max_len = 20 38 | 39 | Quick RI documentation and exact tag jumping 40 | ============================================ 41 | When you're editing a Ruby file, will jump to the definition of the 42 | chosen element if found in the TAGS file; otherwise, it will call RI and show 43 | the documentation in a new window. 44 | You can specify the RI executable to use by adding something like 45 | let g:RCT_ri_cmd = "ri -T -f plain " 46 | to your .vimrc. (rcodetools.vim also honors b:RCT_RI_cmd and w:RCT_RI_cmd if set). 47 | By default, "fri -f plain " will be used. fri (FastRI) is an improved RI 48 | documentation browser, which features more intelligent search modes, gem 49 | integration, vastly better performance... You can find it at 50 | http://eigenclass.org/hiki.rb?fastri and it's also available in gem format 51 | gem install fastri 52 | 53 | If you want to call RI for the word the cursor is on (instead of jumping to 54 | the definition if found), you can use this binding: 55 | r (\r by default if you haven't changed your localleader) 56 | You can specify another binding in your .vimrc as follows: 57 | let g:RCT_ri_binding="" " use ^X^R to call vim on current word 58 | 59 | Using xmpfilter 60 | =============== 61 | xmpfilter takes code from stdin and outputs to stdout so you can filter 62 | your code with ! as usual. 63 | 64 | If you use xmpfilter often, you might want to use mappings like the 65 | following, which allow you to: 66 | * add annotations 67 | * expand assertions 68 | * insert/remove # => markers 69 | 70 | 71 | 72 | " plain annotations 73 | map !xmpfilter -a 74 | nmap V 75 | imap a 76 | 77 | " Test::Unit assertions; use -s to generate RSpec expectations instead 78 | map !xmpfilter -u 79 | nmap V 80 | imap a 81 | 82 | " Annotate the full buffer 83 | " I actually prefer ggVG to %; it's a sort of poor man's visual bell 84 | nmap mzggVG!xmpfilter -a'z 85 | imap 86 | 87 | " assertions 88 | nmap mzggVG!xmpfilter -u'z 89 | imap a 90 | 91 | " Add # => markers 92 | vmap !xmpfilter -m 93 | nmap V 94 | imap a 95 | 96 | " Remove # => markers 97 | vmap ms:call RemoveRubyEval() 98 | nmap V 99 | imap a 100 | 101 | 102 | function! RemoveRubyEval() range 103 | let begv = a:firstline 104 | let endv = a:lastline 105 | normal Hmt 106 | set lz 107 | execute ":" . begv . "," . endv . 's/\s*# \(=>\|!!\).*$//e' 108 | normal 'tzt`s 109 | set nolz 110 | redraw 111 | endfunction 112 | -------------------------------------------------------------------------------- /README.xmpfilter: -------------------------------------------------------------------------------- 1 | 2 | xmpfilter http://eigenclass.org/hiki.rb?xmpfilter 3 | Copyright (c) 2005-2008 Mauricio Fernandez http://eigenclass.org 4 | rubikitch 5 | Use and distribution subject to the terms of the Ruby license. 6 | 7 | Overview 8 | ======== 9 | xmpfilter is a small tool that can be used to 10 | * generate Test::Unit assertions, RSpec expectations and 11 | expectations blocks semi-automatically 12 | * annotate source code with intermediate results (a bit like irb 13 | --simple-prompt but only for the lines explicitly marked with # =>) 14 | Very useful for example code (such as postings to ruby-talk). 15 | 16 | Usage 17 | ===== 18 | xmpfilter takes its input from stdin and writes to stdout. It can run in 19 | several modes (annotation, Test::Unit assertion expansion, RSpec expectation 20 | generation, expectations expectations generation, marker insertion); see 21 | xmpfilter -h 22 | README.emacs and README.vim describe how to use xmpfilter from your editor. 23 | 24 | Example: code annotation 25 | ======================== 26 | Just add "# =>" markers to the lines whose values you want to be shown: 27 | 28 | a, b = "foo", "baz" 29 | a + b # => 30 | a.size # => 31 | 32 | will be expanded to (in one keypress in a decent editor, see README.emacs and 33 | README.vim) 34 | 35 | a, b = "foo", "baz" 36 | a + b # => "foobaz" 37 | a.size # => 3 38 | 39 | This saves much cut&pasting when you're posting to ruby-list/ruby-talk/ruby-core 40 | (We use it all the time). 41 | 42 | 43 | Example: multi-line code annotation 44 | =================================== 45 | Just add "# =>" markers to the next lines whose values you want to be shown with pp: 46 | 47 | a = ["1111111111111111111111111111111111111111111111111111", 123334324234242342, 48 | 1332333333,6,8 ] 49 | 1 # => 50 | a 51 | # => 52 | 53 | will be expanded to (in one keypress in a decent editor, see README.emacs and 54 | README.vim) 55 | 56 | a = ["1111111111111111111111111111111111111111111111111111", 123334324234242342, 57 | 1332333333,6,8 ] 58 | 1 # => 1 59 | a 60 | # => ["1111111111111111111111111111111111111111111111111111", 61 | # 123334324234242342, 62 | # 1332333333, 63 | # 6, 64 | # 8] 65 | 66 | 67 | Example: assertion generation 68 | ============================= 69 | 70 | xmpfilter can generate assertions based on the current behavior of the code 71 | to be tested (iow. the current behavior is assumed to be correct and is used 72 | to generate assertions which won't be modified by further runs of 73 | xmpfilter), making it quite useful for regression testing. 74 | 75 | Imagine you have a ComplexClass you want to test. You might start with 76 | 77 | class TestComplexClass < Test::Unit::TestCase 78 | def setup; @o = ComplexClass.new("foo", false) end 79 | end 80 | 81 | and then want to add some tests: 82 | 83 | def test_insertion 84 | @o.insert "bar" 85 | @o.insert "baz" 86 | # ... assertions here 87 | end 88 | 89 | At this point, you want to add several assertions to verify that the values 90 | returned by @o.size, @o.last, @o.first, @o.complex_computation and @o.last(2) 91 | are correct. You can just write the following and feed the file to 92 | xmpfilter in -u mode (the # => markers can also be inserted by 93 | xmpfilter, see README.vim for more information: 94 | 95 | def test_insertion 96 | @o.insert "bar" 97 | @o.insert "baz" 98 | @o.size # => 99 | @o.last # => 100 | @o.first # => 101 | @o.complex_computation # => 102 | @o.last(2) # => 103 | end 104 | 105 | xmpfilter will run the test and remember what happened in each marked line, 106 | and then rewrite the code so that it looks for instance like 107 | 108 | def test_insertion 109 | @o.insert "bar" 110 | @o.insert "baz" 111 | assert_equal(2, @o.size) 112 | assert_equal("baz", @o.last) 113 | assert_equal("bar", @o.first) 114 | assert_in_delta(3.14159265358979, @o.complex_computation, 0.0001) 115 | assert_equal(["baz", "bar"], @o.last(2)) 116 | end 117 | 118 | As you can see, it can save some typing. 119 | 120 | You can edit the generated assertions as you want: xmpfilter will not 121 | modify lines without the "# =>" marker. xmpfilter can be used repeatedly as 122 | you add more assertions. Imagine you want to verify that @o.last(3) raises an 123 | ArgumentError. You can simply add one line marked with # => : 124 | 125 | ... 126 | assert_in_delta(3.14159265358979, @o.complex_computation, 0.0001) 127 | assert_equal(["baz", "bar"], @o.last(2)) 128 | @o.last(3) # => 129 | end 130 | 131 | and have it expanded by xmpfilter: 132 | 133 | ... 134 | assert_in_delta(3.14159265358979, @o.complex_computation, 0.0001) 135 | assert_equal(["baz", "bar"], @o.last(2)) 136 | assert_raise(ArgumentError){ @o.last(3) } 137 | end 138 | 139 | 140 | Example: RSpec expectations 141 | =========================== 142 | Here's some code before and after filtering it with xmpfilter: 143 | 144 | class X 145 | Y = Struct.new(:a) 146 | def foo(b); b ? Y.new(2) : 2 end 147 | def bar; raise "No good" end 148 | def baz; nil end 149 | def fubar(x); x ** 2.0 + 1 end 150 | def babar; [1,2] end 151 | A = 1 152 | A = 1 153 | end 154 | 155 | context "Testing xmpfilter's expectation expansion" do 156 | setup do 157 | @o = X.new 158 | end 159 | 160 | specify "Should expand should_equal expectations" do 161 | @o.foo(true) # => 162 | @o.foo(true).a # => 163 | @o.foo(false) # => 164 | end 165 | 166 | specify "Should expand should_raise expectations" do 167 | @o.bar # => 168 | end 169 | 170 | specify "Should expand should_be_nil expectations" do 171 | @o.baz # => 172 | end 173 | 174 | specify "Should expand correct expectations for complex values" do 175 | @o.babar # => 176 | end 177 | 178 | specify "Should expand should_be_close expectations" do 179 | @o.fubar(10) # => 180 | end 181 | end 182 | 183 | 184 | after piping it to xmpfilter -s: 185 | 186 | class X 187 | Y = Struct.new(:a) 188 | def foo(b); b ? Y.new(2) : 2 end 189 | def bar; raise "No good" end 190 | def baz; nil end 191 | def fubar(x); x ** 2.0 + 1 end 192 | def babar; [1,2] end 193 | A = 1 194 | A = 1 # !> already initialized constant A 195 | end 196 | 197 | context "Testing xmpfilter's expectation expansion" do 198 | setup do 199 | @o = X.new 200 | end 201 | 202 | specify "Should expand should_equal expectations" do 203 | (@o.foo(true)).should_be_a_kind_of X::Y 204 | (@o.foo(true).inspect).should_equal "#" 205 | (@o.foo(true).a).should_equal 2 206 | (@o.foo(false)).should_equal 2 207 | end 208 | 209 | specify "Should expand should_raise expectations" do 210 | lambda{(@o.bar)}.should_raise RuntimeError 211 | end 212 | 213 | specify "Should expand should_be_nil expectations" do 214 | (@o.baz).should_be_nil 215 | end 216 | 217 | specify "Should expand correct expectations for complex values" do 218 | (@o.babar).should_equal [1, 2] 219 | end 220 | 221 | specify "Should expand should_be_close expectations" do 222 | (@o.fubar(10)).should_be_close(101.0, 0.0001) 223 | end 224 | end 225 | 226 | 227 | Example: expectations expectations 228 | ================================== 229 | Expectations is a light-weight unit testing framework by Jay Fields. 230 | (http://expectations.rubyforge.org) 231 | 232 | Here's some code before and after filtering it with xmpfilter: 233 | 234 | require 'rubygems' 235 | require 'expectations' 236 | 237 | S = Struct.new :a 238 | Expectations do 239 | 1 + 1 # => 240 | "a".length # => 241 | [][1] # => 242 | 1.hoge # => 243 | 1.1 + 1.0 # => 244 | S.new(1) # => 245 | end 246 | 247 | after piping it to xmpfilter --expectations: 248 | 249 | require 'rubygems' 250 | require 'expectations' 251 | 252 | S = Struct.new :a 253 | Expectations do 254 | expect 2 do 255 | 1 + 1 256 | end 257 | 258 | expect 1 do 259 | "a".length 260 | end 261 | 262 | expect nil do 263 | [][1] 264 | end 265 | 266 | expect NoMethodError do 267 | 1.hoge 268 | end 269 | 270 | expect 2.0999..2.1001 do 271 | 1.1 + 1.0 272 | end 273 | 274 | expect S do 275 | S.new(1) 276 | end 277 | 278 | expect "#" do 279 | S.new(1).inspect 280 | end 281 | 282 | end 283 | 284 | 285 | License 286 | ======= 287 | xmpfilter is licensed under the same terms as Ruby. 288 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | 2 | PKG_REVISION = ".0" 3 | 4 | $:.unshift "lib" if File.directory? "lib" 5 | require 'rcodetools/xmpfilter' 6 | require 'rake/testtask' 7 | include Rcodetools 8 | RCT_VERSION = XMPFilter::VERSION 9 | 10 | desc "Run the unit tests in pure-Ruby mode ." 11 | Rake::TestTask.new(:test) do |t| 12 | t.libs << "ext/rcovrt" 13 | t.test_files = FileList['test/test*.rb'] 14 | t.verbose = true 15 | end 16 | 17 | require 'rcov/rcovtask' 18 | desc "Run rcov." 19 | Rcov::RcovTask.new do |t| 20 | t.rcov_opts << "--xrefs" # comment to disable cross-references 21 | t.test_files = FileList['test/test_*.rb'].to_a - ["test/test_functional.rb"] 22 | t.verbose = true 23 | end 24 | 25 | desc "Save current coverage state for later comparisons." 26 | Rcov::RcovTask.new(:rcovsave) do |t| 27 | t.rcov_opts << "--save" 28 | t.test_files = FileList['test/test_*.rb'].to_a - ["test/test_functional.rb"] 29 | t.verbose = true 30 | end 31 | 32 | task :default => :test 33 | 34 | 35 | #{{{ Package tasks 36 | PKG_FILES = FileList[ 37 | "bin/xmpfilter", "bin/rct-*", "bin/ruby-toggle-file", "bin/rbtest", 38 | "lib/**/*.rb", 39 | "CHANGES", "rcodetools.*", "icicles-rcodetools.el", "anything-rcodetools.el", 40 | "README", "README.*", "THANKS", 41 | "Rakefile", "Rakefile.method_analysis", 42 | "setup.rb", 43 | "test/**/*.rb","test/**/*.taf" 44 | ] 45 | 46 | begin 47 | require 'rake/gempackagetask' 48 | Spec = Gem::Specification.new do |s| 49 | s.name = "rcodetools" 50 | s.version = RCT_VERSION + PKG_REVISION 51 | s.summary = "rcodetools is a collection of Ruby code manipulation tools" 52 | s.description = <, "Mauricio Fernandez" } 67 | s.homepage = "http://eigenclass.org/hiki.rb?rcodetools" 68 | s.bindir = "bin" 69 | s.executables = %w[rct-complete rct-doc xmpfilter rct-meth-args] 70 | s.has_rdoc = true 71 | s.extra_rdoc_files = %w[README] 72 | s.rdoc_options << "--main" << "README" << "--title" << 'rcodetools' 73 | s.test_files = Dir["test/test_*.rb"] 74 | s.post_install_message = < [:test] 96 | Rake::GemPackageTask.new(Spec) do |p| 97 | p.need_tar_gz = true 98 | end 99 | 100 | rescue LoadError 101 | # RubyGems not installed 102 | end 103 | 104 | desc "install by setup.rb" 105 | task :install do 106 | sh "sudo ruby setup.rb install" 107 | end 108 | 109 | desc "release in rubyforge" 110 | task :release => [:package] do 111 | sh "rubyforge login" 112 | sh "rubyforge add_release rcodetools rcodetools #{RCT_VERSION} pkg/rcodetools-#{RCT_VERSION}.0.tar.gz " 113 | sh "rubyforge add_file rcodetools rcodetools #{RCT_VERSION} pkg/rcodetools-#{RCT_VERSION}.0.gem " 114 | end 115 | 116 | # vim: set sw=2 ft=ruby: 117 | -------------------------------------------------------------------------------- /Rakefile.method_analysis: -------------------------------------------------------------------------------- 1 | 2 | # Rake tasks to generate TAGS and gather method analysis information. 3 | # See README.method_analysis for more information. 4 | 5 | ## my standard Rakefile 6 | task :tags => "TAGS" 7 | 8 | desc "Generate method_analysis by ruby -rmethod_analyzer." 9 | task :analyze => [:_prepare_method_analyze, :tags] do 10 | at_exit { sh "ls -l method_analysis" } 11 | end 12 | 13 | task :_prepare_method_analyze do 14 | ENV['METHOD_ANALYZER_FORMAT']="marshal" 15 | sh "rm -f method_analysis" 16 | puts "generating method_analysis" 17 | end 18 | 19 | ## application-specific Rakefile (RTtool) 20 | task :analyze do 21 | sh "ruby -Ilib -rmethod_analyzer test/test.rb" 22 | sh "ruby -Ilib -rmethod_analyzer test/test-rt2html-lib.rb" 23 | sh "ruby -Ilib -rmethod_analyzer test/test-rtparser.rb" 24 | end 25 | 26 | file "TAGS" => FileList["lib/rt/*.rb"] do 27 | sh "rct-meth-args -t lib/rt/*.rb > TAGS" 28 | end 29 | 30 | 31 | -------------------------------------------------------------------------------- /THANKS: -------------------------------------------------------------------------------- 1 | Some names forgotten, tell me if you care :) -- mfp 2 | 3 | rubikitch 4 | * expanded xmp3.rb (a previous version of xmpfilter.rb) to support RSpec expectations 5 | * wrote the elisp magic to use xmpfilter.rb with emacs 6 | * made the 100% accurate, editor-independent completion system 7 | [rubikitch took xmpfilter and turned it into the much more powerful 8 | rcodetools, so there are way too many things to list them here :)] 9 | 10 | Adagios 11 | * found & fixed problem with rcodetools.vim plugin on win32 12 | -------------------------------------------------------------------------------- /anything-rcodetools.el: -------------------------------------------------------------------------------- 1 | ;;; anything-rcodetools.el --- accurate Ruby method completion with anything 2 | ;; $Id: anything-rcodetools.el,v 1.13 2009/04/20 16:25:37 rubikitch Exp $ 3 | 4 | ;;; Copyright (c) 2007 rubikitch 5 | 6 | ;; Author: rubikitch 7 | ;; URL: http://www.emacswiki.org/cgi-bin/wiki/download/anything-rcodetools.el 8 | 9 | ;;; Use and distribution subject to the terms of the Ruby license. 10 | 11 | ;;; Commentary: 12 | 13 | ;; (0) You need rcodetools, anything.el and FastRI. Note that you do not have to 14 | ;; configure anything.el if you use anything.el for this package. 15 | ;; (1) You need to add to .emacs: 16 | ;; (require 'anything) 17 | ;; (require 'anything-rcodetools) 18 | ;; ;; Command to get all RI entries. 19 | ;; (setq rct-get-all-methods-command "PAGER=cat fri -l") 20 | ;; ;; See docs 21 | ;; (define-key anything-map "\C-z" 'anything-execute-persistent-action) 22 | 23 | ;;; Commands: 24 | ;; 25 | ;; Below are complete command list: 26 | ;; 27 | ;; 28 | ;;; Customizable Options: 29 | ;; 30 | ;; Below are customizable option list: 31 | ;; 32 | 33 | ;;; History: 34 | 35 | ;; $Log: anything-rcodetools.el,v $ 36 | ;; Revision 1.13 2009/04/20 16:25:37 rubikitch 37 | ;; Set anything-samewindow to nil 38 | ;; 39 | ;; Revision 1.12 2009/04/18 10:12:02 rubikitch 40 | ;; Adjust to change of `use-anything-show-completion' 41 | ;; 42 | ;; Revision 1.11 2009/04/17 20:21:47 rubikitch 43 | ;; * require anything 44 | ;; * require anything-show-completion.el if available 45 | ;; 46 | ;; Revision 1.10 2009/04/17 20:11:03 rubikitch 47 | ;; removed old code 48 | ;; 49 | ;; Revision 1.9 2009/04/17 20:07:52 rubikitch 50 | ;; * use --completion-emacs-anything option 51 | ;; * New implementation of `anything-c-source-complete-ruby-all' 52 | ;; 53 | ;; Revision 1.8 2009/04/15 10:25:25 rubikitch 54 | ;; Set `anything-execute-action-at-once-if-one' t 55 | ;; 56 | ;; Revision 1.7 2009/04/15 10:24:23 rubikitch 57 | ;; regexp bug fix 58 | ;; 59 | ;; Revision 1.6 2008/01/14 17:59:34 rubikitch 60 | ;; * uniform format (anything-c-source-complete-ruby, anything-c-source-complete-ruby-all) 61 | ;; * rename command: anything-c-ri -> anything-rct-ri 62 | ;; 63 | ;; Revision 1.5 2008/01/13 17:54:04 rubikitch 64 | ;; anything-current-buffer advice. 65 | ;; 66 | ;; Revision 1.4 2008/01/08 14:47:34 rubikitch 67 | ;; Added (require 'rcodetools). 68 | ;; Revised commentary. 69 | ;; 70 | ;; Revision 1.3 2008/01/04 09:32:29 rubikitch 71 | ;; *** empty log message *** 72 | ;; 73 | ;; Revision 1.2 2008/01/04 09:21:23 rubikitch 74 | ;; fixed typo 75 | ;; 76 | ;; Revision 1.1 2008/01/04 09:21:05 rubikitch 77 | ;; Initial revision 78 | ;; 79 | 80 | ;;; Code: 81 | 82 | (require 'anything) 83 | (require 'rcodetools) 84 | (when (require 'anything-show-completion nil t) 85 | (use-anything-show-completion 'rct-complete-symbol--anything 86 | '(length pattern))) 87 | 88 | (defun anything-rct-ri (meth) 89 | (ri (get-text-property 0 'desc meth))) 90 | 91 | (defun anything-rct-complete (meth) 92 | (save-excursion 93 | (set-buffer anything-current-buffer) 94 | (search-backward pattern) 95 | (delete-char (length pattern))) 96 | (insert meth)) 97 | 98 | (setq rct-complete-symbol-function 'rct-complete-symbol--anything) 99 | (defvar anything-c-source-complete-ruby 100 | '((name . "Ruby Method Completion") 101 | (candidates . rct-method-completion-table) 102 | (init 103 | . (lambda () 104 | (condition-case x 105 | (rct-exec-and-eval rct-complete-command-name "--completion-emacs-anything") 106 | ((error) (setq rct-method-completion-table nil))))) 107 | (action 108 | ("Completion" . anything-rct-complete) 109 | ("RI" . anything-rct-ri)) 110 | (volatile) 111 | (persistent-action . anything-rct-ri))) 112 | 113 | (defvar rct-get-all-methods-command "PAGER=cat fri -l") 114 | (defvar anything-c-source-complete-ruby-all 115 | '((name . "Ruby Method Completion (ALL)") 116 | (init 117 | . (lambda () 118 | (unless (anything-candidate-buffer) 119 | (with-current-buffer (anything-candidate-buffer 'global) 120 | (call-process-shell-command rct-get-all-methods-command nil t) 121 | (goto-char 1) 122 | (while (re-search-forward "^.+[:#.]\\([^:#.]+\\)$" nil t) 123 | (replace-match "\\1\t[\\&]")))))) 124 | (candidates-in-buffer 125 | . (lambda () 126 | (let ((anything-pattern (format "^%s.*%s" (regexp-quote pattern) anything-pattern))) 127 | (anything-candidates-in-buffer)))) 128 | (display-to-real 129 | . (lambda (line) 130 | (if (string-match "\t\\[\\(.+\\)\\]$" line) 131 | (propertize (substring line 0 (match-beginning 0)) 132 | 'desc (match-string 1 line)) 133 | line))) 134 | (action 135 | ("Completion" . anything-rct-complete) 136 | ("RI" . anything-rct-ri)) 137 | (persistent-action . anything-rct-ri))) 138 | 139 | 140 | (defun rct-complete-symbol--anything () 141 | (interactive) 142 | (let ((anything-execute-action-at-once-if-one t) 143 | anything-samewindow) 144 | (anything '(anything-c-source-complete-ruby 145 | anything-c-source-complete-ruby-all)))) 146 | 147 | (provide 'anything-rcodetools) 148 | 149 | ;; How to save (DO NOT REMOVE!!) 150 | ;; (emacswiki-post "anything-rcodetools.el") 151 | ;;; install-elisp.el ends here 152 | -------------------------------------------------------------------------------- /bin/rbtest: -------------------------------------------------------------------------------- 1 | #! /usr/local/bin/ruby18 2 | # Copyright (c) 2006-2007 rubikitch 3 | # 4 | # Use and distribution subject to the terms of the Ruby license. 5 | 6 | USAGE = <<'XXX' 7 | Usage: rbtest SCRIPT [-S RUBY_INTERPRETER] [Test::Unit OPTIONS] 8 | Usage: rbtest [-h] [--help] [--example] 9 | 10 | I am rbtest, embedded Test::Unit executor for one-file scripts. 11 | Splitting a small script into many files (executables, libraries and tests) is cumbersome. 12 | And it is handy to put unit tests near implementations like D language, which has 13 | built-in unittest keyword. 14 | 15 | Embedded Test::Unit is simpler than vanilla Test::Unit. 16 | You do not have to define a Test::Unit::TestCase subclass, 17 | it is automagically defined and executed by me. 18 | Embedded Test::Unit uses =begin/=end comment blocks. 19 | 20 | "=begin TEST_METHOD_NAME" blocks define test methods, eg. "=begin test_foo". 21 | "=begin rbtest" blocks define utility methods and setup/teardown methods. 22 | 23 | Of course, you MUST use "if __FILE__ ==$0" idiom to split executable and class/method/function. 24 | 25 | I am also an real-life example of rbtest usage. 26 | Issue: 27 | rbtest --example 28 | to show me. 29 | 30 | 31 | options: 32 | -h, --help Print usage. 33 | -S RUBY_INTERPRETER Use Ruby interpreter RUBY_INTERPRETER. 34 | --example Print this file. 35 | --output Print internally-generated test script (for debug). 36 | XXX 37 | 38 | 39 | def first_test(script_filename) 40 | "require 'test/unit';" + 41 | "load '#{script_filename}';" + 42 | "class TestByRbtest < Test::Unit::TestCase;" 43 | end 44 | 45 | =begin rbtest 46 | def setup 47 | end 48 | 49 | def unindent(s) 50 | s.map{|x| x[1..-1]}.join 51 | end 52 | =end 53 | 54 | =begin test_script_to_test_script 55 | # indent is needed to avoid syntax error. 56 | script = < markers.") do 33 | klass = XMPAddMarkers 34 | end 35 | 36 | opts.handle_interpreter options 37 | 38 | opts.separator "" 39 | opts.separator "Specific options:" 40 | opts.on("-l N", "--min-line-length N", Integer, "Align markers to N spaces.") do |min_codeline_size| 41 | options[:min_codeline_size] = min_codeline_size 42 | end 43 | opts.on("--rails", "Setting appropriate for Rails.", 44 | "(no warnings, find working directory,", 45 | " Test::Unit assertions)") do 46 | require 'rcodetools/xmptestunitfilter' 47 | options[:warnings] = false 48 | klass = XMPTestUnitFilter 49 | rails_settings = true 50 | end 51 | opts.on("--[no-]poetry", "Whether to use extra parentheses.", 52 | "(default: use them)") do |poetry_p| 53 | options[:use_parentheses] = !poetry_p 54 | end 55 | opts.on("--[no-]warnings", "Whether to add warnings (# !>).", 56 | "(default: enabled)") {|warnings_p| options[:warnings] = warnings_p } 57 | opts.on("-q", "--quiet", "Supress standard output.") do 58 | options[:output_stdout] = false 59 | end 60 | 61 | opts.handle_misc options 62 | end 63 | 64 | set_extra_opts options 65 | opts.parse!(ARGV) 66 | 67 | if rails_settings && !options[:wd] 68 | if File.exist? ARGF.path 69 | options[:wd] = File.dirname(ARGF.path) 70 | elsif File.exist? "test/unit" 71 | options[:wd] = "test/unit" 72 | elsif File.exist? "unit" 73 | options[:wd] = "unit" 74 | end 75 | end 76 | targetcode = ARGF.read 77 | Dir.chdir options[:wd] if options[:wd] 78 | 79 | if XMPFilter.detect_rbtest(targetcode, options) 80 | require 'rcodetools/xmptestunitfilter' 81 | klass = XMPTestUnitFilter 82 | end 83 | 84 | # Do the job. dispatched by klass. 85 | puts klass.run(targetcode, options) 86 | -------------------------------------------------------------------------------- /icicles-rcodetools.el: -------------------------------------------------------------------------------- 1 | ;;; icicles-rcodetools.el -- accurate completion with icicles 2 | 3 | ;;; Copyright (c) 2006-2007 rubikitch 4 | ;;; 5 | ;;; Use and distribution subject to the terms of the Ruby license. 6 | 7 | (require 'icicles) 8 | (require 'rcodetools) 9 | 10 | (setq rct-complete-symbol-function 'rct-complete-symbol--icicles) 11 | (icicle-define-command rct-complete-symbol--icicles 12 | "Perform ruby method and class completion on the text around point with icicles. 13 | C-M-RET shows RI documentation on each candidate. 14 | See also `rct-interactive'." 15 | 16 | (lambda (result) 17 | (save-excursion 18 | (search-backward pattern) 19 | (setq beg (point))) 20 | (delete-region beg end) 21 | (insert result)) ;/function 22 | "rct-complete: " ;prompt 23 | rct-method-completion-table 24 | nil nil pattern nil nil nil 25 | ((end (point)) beg 26 | (icicle-list-join-string "\t") 27 | (icicle-list-use-nth-parts '(1)) 28 | (icicle-point-position-in-candidate 'input-end) 29 | pattern klass alist 30 | (icicle-candidate-help-fn 31 | (lambda (result) 32 | (ri (cdr (assoc result alist)))))) ;bindings 33 | (rct-exec-and-eval rct-complete-command-name "--completion-emacs-icicles")) 34 | 35 | (provide 'icicles-rcodetools) 36 | -------------------------------------------------------------------------------- /lib/method_analyzer.rb: -------------------------------------------------------------------------------- 1 | class Module 2 | remove_method :attr_reader 3 | def attr_reader(*names) 4 | names.each do |name| 5 | module_eval "def #{name}() @#{name} end" 6 | end 7 | end 8 | remove_method :attr_writer 9 | def attr_writer(*names) 10 | names.each do |name| 11 | module_eval "def #{name}=(x) @#{name}=x end" 12 | end 13 | end 14 | remove_method :attr_accessor 15 | def attr_accessor(*names) 16 | attr_reader(*names) 17 | attr_writer(*names) 18 | end 19 | remove_method :attr 20 | def attr(name, writer=false) 21 | attr_reader name 22 | attr_writer name if writer 23 | end 24 | end 25 | 26 | 27 | module MethodAnalyzer 28 | @@methods = Hash.new{ |h,k| h[k] = Hash.new{ |h,k| h[k] = []} } 29 | @@whereis = [] 30 | @@expand_path = Hash.new{ |h,k| h[k] = File.expand_path(k)} 31 | 32 | def self.trace_func(event, file, line, id, binding, klass, *rest) 33 | return if file == __FILE__ 34 | return if (event != 'call' and event != 'c-call') 35 | return if klass == Class and id == :inherited 36 | return if klass == Module and id == :method_added 37 | return if klass == Kernel and id == :singleton_method_added 38 | saved_crit = Thread.critical 39 | Thread.critical = true 40 | 41 | the_self = eval("self",binding) 42 | flag = Class === the_self ? "." : "#" 43 | #klass = klass == Kernel ? Object : klass 44 | fullname = "#{klass}#{flag}#{id}" 45 | file.replace @@expand_path[file] 46 | if event == 'call' 47 | @@whereis << [file, line, fullname] if file !~ /\(eval\)$/ 48 | file, line, rest = caller(4)[0].split(/:/) 49 | file.replace @@expand_path[file] # DRY 50 | p caller(0) if $DEBUG 51 | line = line.to_i 52 | end 53 | @@methods[file][line] << fullname if event =~ /call/ 54 | 55 | Thread.critical = saved_crit 56 | end 57 | 58 | def self.at_exit__output_marshal 59 | at_exit do 60 | set_trace_func nil 61 | dbfile = "method_analysis" 62 | old = Marshal.load(File.read(dbfile)) rescue {} 63 | open(dbfile, "wb") do |io| 64 | # Because Marshal.dump cannot handle hashes with default_proc 65 | @@methods.default = nil 66 | @@methods.each_value{ |v| v.default=nil; v.each_value{ |vv| vv.uniq! } } 67 | Marshal.dump(@@methods.merge(old), io) 68 | end 69 | end 70 | end 71 | 72 | 73 | def self.at_exit__output_text 74 | at_exit do 75 | set_trace_func nil 76 | puts "method fullnames" 77 | @@methods.sort.each do |file, lines| 78 | lines.sort.each do |line, methods| 79 | printf "%s:%s:%s\n", file, line, methods.uniq.join(" ") 80 | end 81 | end 82 | 83 | puts 84 | puts "method definitions" 85 | @@whereis.sort.uniq.each do |file, line, fullname | 86 | printf "%s:%s:%s\n", file, line, fullname 87 | end 88 | 89 | end 90 | end 91 | 92 | def self.set_at_exit 93 | case ENV['METHOD_ANALYZER_FORMAT'] 94 | when 'marshal' 95 | at_exit__output_marshal 96 | else 97 | at_exit__output_text 98 | end 99 | end 100 | 101 | set_at_exit 102 | set_trace_func method(:trace_func).to_proc 103 | end 104 | 105 | if __FILE__ == $0 106 | load "./test/data/method_analyzer-data.rb" 107 | end 108 | -------------------------------------------------------------------------------- /lib/rcodetools/compat.rb: -------------------------------------------------------------------------------- 1 | if RUBY_VERSION >= "1.9" 2 | class String 3 | alias :each :each_line 4 | include Enumerable 5 | end 6 | 7 | module Enumerable 8 | alias :enum_with_index :each_with_index 9 | end 10 | 11 | class Array 12 | alias :to_s :join 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/rcodetools/doc.rb: -------------------------------------------------------------------------------- 1 | require 'rcodetools/completion' 2 | # Call Ri for any editors!! 3 | # by rubikitch 4 | module Rcodetools 5 | 6 | class XMPDocFilter < XMPFilter 7 | include ProcessParticularLine 8 | 9 | def initialize(opts = {}) 10 | super 11 | @filename = opts[:filename] 12 | extend UseMethodAnalyzer if opts[:use_method_analyzer] 13 | end 14 | 15 | def self.run(code, opts) 16 | new(opts).doc(code, opts[:lineno], opts[:column]) 17 | end 18 | 19 | def prepare_line(expr, column) 20 | set_expr_and_postfix!(expr, column){|c| 21 | withop_re = /^.{#{c-1}}[#{OPERATOR_CHARS}]+/ 22 | if expr =~ withop_re 23 | withop_re 24 | else 25 | /^.{#{c}}[\w#{OPERATOR_CHARS}]*/ 26 | end 27 | } 28 | recv = expr 29 | 30 | # When expr already knows receiver and method, 31 | return(__prepare_line :recv => expr.eval_string, :meth => expr.meth) if expr.eval_string 32 | 33 | case expr 34 | when /^(?:::)?([A-Z].*)(?:::|\.)(.*)$/ # nested constants / class methods 35 | __prepare_line :klass => $1, :meth_or_constant => $2 36 | when /^(?:::)?[A-Z]/ # normal constants 37 | __prepare_line :klass => expr 38 | when /\.([^.]*)$/ # method call 39 | __prepare_line :recv => Regexp.last_match.pre_match, :meth => $1 40 | when /^(.+)(\[\]=?)$/ # [], []= 41 | __prepare_line :recv => $1, :meth => $2 42 | when /[#{OPERATOR_CHARS}]+$/ # operator 43 | __prepare_line :recv => Regexp.last_match.pre_match, :meth => $& 44 | else # bare words 45 | __prepare_line :recv => "self", :meth => expr 46 | end 47 | end 48 | 49 | def __prepare_line(x) 50 | v = "#{VAR}" 51 | result = "#{VAR}_result" 52 | klass = "#{VAR}_klass" 53 | flag = "#{VAR}_flag" 54 | which_methods = "#{VAR}_methods" 55 | ancestor_class = "#{VAR}_ancestor_class" 56 | idx = 1 57 | recv = x[:recv] || x[:klass] || raise(ArgumentError, "need :recv or :klass") 58 | meth = x[:meth_or_constant] || x[:meth] 59 | debugprint "recv=#{recv}", "meth=#{meth}" 60 | if meth 61 | # imported from fastri/MagicHelp 62 | code = <<-EOC 63 | #{v} = (#{recv}) 64 | $stderr.print("#{MARKER}[#{idx}] => " + #{v}.class.to_s + " ") 65 | 66 | if Module === #{v} and '#{meth}' =~ /^[A-Z]/ and #{v}.const_defined?('#{meth}') 67 | #{result} = #{v}.to_s + "::#{meth}" 68 | else 69 | #{__magic_help_code result, v, meth.dump} 70 | end 71 | 72 | $stderr.puts(#{result}) 73 | exit 74 | EOC 75 | else 76 | code = <<-EOC 77 | #{v} = (#{recv}) 78 | $stderr.print("#{MARKER}[#{idx}] => " + #{v}.class.to_s + " ") 79 | $stderr.puts(#{v}.to_s) 80 | exit 81 | EOC 82 | end 83 | oneline_ize(code) 84 | end 85 | 86 | # overridable by module 87 | def _doc(code, lineno, column) 88 | end 89 | 90 | def doc(code, lineno, column=nil) 91 | _doc(code, lineno, column) or runtime_data(code, lineno, column).to_s 92 | end 93 | 94 | module UseMethodAnalyzer 95 | METHOD_ANALYSIS = "method_analysis" 96 | def have_method_analysis 97 | File.file? METHOD_ANALYSIS 98 | end 99 | 100 | def find_method_analysis 101 | here = Dir.pwd 102 | oldpwd = here 103 | begin 104 | while ! have_method_analysis 105 | Dir.chdir("..") 106 | if Dir.pwd == here 107 | return nil # not found 108 | end 109 | here = Dir.pwd 110 | end 111 | ensure 112 | Dir.chdir oldpwd 113 | end 114 | yield(File.join(here, METHOD_ANALYSIS)) 115 | end 116 | 117 | def _doc(code, lineno, column=nil) 118 | find_method_analysis do |ma_file| 119 | methods = open(ma_file, "rb"){ |f| Marshal.load(f)} 120 | line = File.readlines(@filename)[lineno-1] 121 | current_method = line[ /^.{#{column}}\w*/][ /\w+[\?!]?$/ ].sub(/:+/,'') 122 | filename = @filename # FIXME 123 | begin 124 | methods[filename][lineno].grep(Regexp.new(Regexp.quote(current_method)))[0] 125 | rescue NoMethodError 126 | raise "doc/method_analyzer:cannot find #{current_method}" 127 | end 128 | 129 | end 130 | end 131 | end 132 | 133 | end 134 | 135 | # ReFe is so-called `Japanese Ri'. 136 | class XMPReFeFilter < XMPDocFilter 137 | def doc(code, lineno, column=nil) 138 | "refe '#{super}'" 139 | end 140 | end 141 | 142 | class XMPRiFilter < XMPDocFilter 143 | def doc(code, lineno, column=nil) 144 | "ri '#{super.sub(/\./, '::')}'" 145 | end 146 | end 147 | 148 | class XMPRiEmacsFilter < XMPDocFilter 149 | def doc(code, lineno, column=nil) 150 | begin 151 | %!(rct-find-tag-or-ri "#{super}")! 152 | rescue Exception => err 153 | return %Q[(error "#{err.message}")] 154 | end 155 | end 156 | end 157 | 158 | class XMPRiVimFilter < XMPDocFilter 159 | def doc(code, lineno, column=nil) 160 | begin 161 | %{call RCT_find_tag_or_ri("#{super}")} 162 | rescue Exception => err 163 | return %Q[echo #{err.message.inspect}] 164 | end 165 | end 166 | end 167 | 168 | end 169 | -------------------------------------------------------------------------------- /lib/rcodetools/fork.rb: -------------------------------------------------------------------------------- 1 | ## Rcodetools version of ruby_fork 2 | # 3 | # Based on ruby_fork.rb by Ryan Davis, Eric Hodel, Zen Spider Software 4 | # 5 | # (The MIT License) 6 | # 7 | # Copyright (c) 2006 Ryan Davis, Eric Hodel, Zen Spider Software 8 | # 2007 rubikitch 9 | # 10 | # Permission is hereby granted, free of charge, to any person obtaining 11 | # a copy of this software and associated documentation files (the 12 | # "Software"), to deal in the Software without restriction, including 13 | # without limitation the rights to use, copy, modify, merge, publish, 14 | # distribute, sublicense, and/or sell copies of the Software, and to 15 | # permit persons to whom the Software is furnished to do so, subject to 16 | # the following conditions: 17 | # 18 | # The above copyright notice and this permission notice shall be 19 | # included in all copies or substantial portions of the Software. 20 | # 21 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 24 | # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 25 | # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 26 | # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 27 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | 29 | require 'optparse' 30 | require 'socket' 31 | require 'rcodetools/fork_config' 32 | 33 | module Rcodetools 34 | module Fork 35 | 36 | USAGE_HELP = < [], 59 | :code => [], 60 | :extra_paths => [], 61 | :port => PORT, 62 | } 63 | 64 | def self.add_env_args(opts, settings) 65 | opts.separator '' 66 | opts.separator 'Process environment options:' 67 | 68 | opts.separator '' 69 | opts.on('-e CODE', 'Execute CODE in parent process.', 70 | 'May be specified multiple times.') do |code| 71 | settings[:code] << code 72 | end 73 | 74 | opts.separator '' 75 | opts.on('-I DIRECTORY', 'Adds DIRECTORY to $LOAD_PATH.', 76 | 'May be specified multiple times.') do |dir| 77 | settings[:extra_paths] << dir 78 | end 79 | 80 | opts.separator '' 81 | opts.on('-r LIBRARY', 'Require LIBRARY in the parent process.', 82 | 'May be specified multiple times.') do |lib| 83 | settings[:requires] << lib 84 | end 85 | end 86 | 87 | def self.daemonize(io = File.open('/dev/null', 'r+')) 88 | fork and exit! 89 | Process.setsid 90 | fork and exit! 91 | 92 | STDIN.reopen io 93 | STDOUT.reopen io 94 | STDERR.reopen io 95 | 96 | yield if block_given? 97 | end 98 | 99 | def self.parse_client_args(args) 100 | settings = Marshal.load Marshal.dump(DEFAULT_SETTINGS) 101 | 102 | opts = OptionParser.new do |opts| 103 | opts.banner = "Usage: #{$0} [options]\n#{USAGE_HELP}" 104 | 105 | opts.separator '' 106 | opts.on('-p', '--port PORT', 107 | 'Listen for connections on PORT.', 108 | "Default: #{settings[:port]}") do |port| 109 | settings[:port] = port.to_i 110 | end 111 | 112 | opts.separator '' 113 | opts.on('-h', '--help', 'You\'re looking at it.') do 114 | $stderr.puts opts 115 | exit 1 116 | end 117 | 118 | add_env_args opts, settings 119 | end 120 | 121 | opts.parse! args 122 | 123 | return settings 124 | end 125 | 126 | def self.parse_server_args(args) 127 | settings = Marshal.load Marshal.dump(DEFAULT_SETTINGS) 128 | 129 | opts = OptionParser.new do |opts| 130 | opts.banner = "Usage: #{$0} [options]\n#{USAGE_HELP}" 131 | 132 | opts.separator '' 133 | opts.on('-p', '--port PORT', 134 | 'Listen for connections on PORT.', 135 | "Default: #{settings[:port]}") do |port| 136 | settings[:port] = port.to_i 137 | end 138 | 139 | opts.separator '' 140 | opts.on('-h', '--help', 'You\'re looking at it.') do 141 | $stderr.puts opts 142 | exit 1 143 | end 144 | 145 | add_env_args opts, settings 146 | end 147 | 148 | opts.parse! args 149 | 150 | return settings 151 | end 152 | 153 | def self.start_client(args = ARGV) 154 | trap 'INT' do exit 1 end # Exit gracefully 155 | 156 | settings = parse_client_args args 157 | 158 | args = Marshal.dump [settings, ARGV] 159 | 160 | socket = TCPSocket.new 'localhost', settings[:port] 161 | 162 | socket.puts args.length 163 | socket.write args 164 | socket.close_write 165 | 166 | until socket.eof? 167 | $stdout.puts socket.gets 168 | end 169 | end 170 | 171 | def self.start_server(args = ARGV) 172 | begin 173 | require 'rubygems' 174 | rescue LoadError 175 | end 176 | write_pwd 177 | settings = parse_server_args args 178 | setup_environment settings 179 | 180 | server = TCPServer.new 'localhost', settings[:port] 181 | 182 | $stderr.puts "#{$0} Running as PID #{$$} on #{settings[:port]}" 183 | 184 | loop do 185 | Thread.new server.accept do |socket| 186 | begin 187 | args_length = socket.gets.to_i 188 | args = socket.read args_length 189 | settings, argv = Marshal.load args 190 | 191 | fork do 192 | daemonize socket do 193 | ARGV.replace argv 194 | setup_environment settings 195 | socket.close 196 | end 197 | end 198 | 199 | socket.close # close my copy. 200 | rescue => e 201 | socket.close if socket 202 | end 203 | end 204 | end 205 | rescue Interrupt, SystemExit 206 | File.unlink PWD_FILE 207 | rescue Exception => e 208 | File.unlink PWD_FILE 209 | puts "Failed to catch #{e.class}:#{e.message}" 210 | puts "\t#{e.backtrace.join "\n\t"}" 211 | end 212 | 213 | def self.setup_environment(settings) 214 | settings[:extra_paths].map! { |dir| dir.split ':' } 215 | settings[:extra_paths].flatten! 216 | settings[:extra_paths].each { |dir| $:.unshift dir } 217 | 218 | begin 219 | settings[:requires].each { |file| require file } 220 | settings[:code].each { |code| eval code, TOPLEVEL_BINDING } 221 | rescue Exception 222 | $@.reject! {|s| s =~ %r!rcodetools/fork\.rb!} 223 | raise 224 | end 225 | end 226 | 227 | end 228 | 229 | end 230 | -------------------------------------------------------------------------------- /lib/rcodetools/fork_config.rb: -------------------------------------------------------------------------------- 1 | 2 | module Rcodetools 3 | 4 | module Fork 5 | PORT = 9085 6 | # Contains $PWD of rct-fork server. Exists only while running. 7 | PWD_FILE = File.expand_path "~/.rct-fork.pwd" 8 | 9 | def self.chdir_fork_directory 10 | if run? 11 | Dir.chdir File.read(PWD_FILE) 12 | else 13 | raise "rct-fork is not running." 14 | end 15 | end 16 | 17 | def self.write_pwd 18 | open(PWD_FILE, "w"){|f| f.print Dir.pwd } 19 | end 20 | 21 | def self.run? 22 | File.file? PWD_FILE 23 | end 24 | end 25 | 26 | end 27 | -------------------------------------------------------------------------------- /lib/rcodetools/options.rb: -------------------------------------------------------------------------------- 1 | require 'optparse' 2 | 3 | module Rcodetools 4 | # Domain specific OptionParser extensions 5 | module OptionHandler 6 | def set_banner 7 | self.banner = "Usage: #{$0} [options] [inputfile] [-- cmdline args]" 8 | end 9 | 10 | def handle_position(options) 11 | separator "" 12 | separator "Position options:" 13 | on("--line=LINE", "Current line number.") do |n| 14 | options[:lineno] = n.to_i 15 | end 16 | on("--column=COLUMN", "Current column number in BYTE.") do |n| 17 | options[:column] = n.to_i 18 | end 19 | on("-t TEST", "--test=TEST", 20 | "Execute test script. ", 21 | "TEST is TESTSCRIPT, TESTSCRIPT@TESTMETHOD, or TESTSCRIPT@LINENO.", 22 | "You must specify --filename option.") do |t| 23 | options[:test_script], options[:test_method] = t.split(/@/) 24 | end 25 | on("--filename=FILENAME", "Filename of standard input.") do |f| 26 | options[:filename] = f 27 | end 28 | end 29 | 30 | def handle_interpreter(options) 31 | separator "" 32 | separator "Interpreter options:" 33 | on("-S FILE", "--interpreter FILE", "Use interpreter FILE.") do |interpreter| 34 | options[:interpreter] = interpreter 35 | end 36 | on("-I PATH", "Add PATH to $LOAD_PATH") do |path| 37 | options[:include_paths] << path 38 | end 39 | on("--dev", "Add this project's bin/ and lib/ to $LOAD_PATH.", 40 | "A directory with a Rakefile is considered a project base directory.") do 41 | auto_include_paths(options[:include_paths], Dir.pwd) 42 | end 43 | on("-r LIB", "Require LIB before execution.") do |lib| 44 | options[:libs] << lib 45 | end 46 | on("-e EXPR", "--eval=EXPR", "--stub=EXPR", "Evaluate EXPR after execution.") do |expr| 47 | options[:evals] << expr 48 | end 49 | on("--fork", "Use rct-fork-client if rct-fork is running.") do 50 | options[:detect_rct_fork] = true 51 | end 52 | on("--rbtest", "Use rbtest.") do 53 | options[:use_rbtest] = true 54 | end 55 | on("--detect-rbtest", "Use rbtest if '=begin test_*' blocks exist.") do 56 | options[:detect_rbtest] = true 57 | end 58 | end 59 | 60 | def handle_misc(options) 61 | separator "" 62 | separator "Misc options:" 63 | on("--cd DIR", "Change working directory to DIR.") do |dir| 64 | options[:wd] = dir 65 | end 66 | on("--debug", "Write transformed source code to xmp-tmp.PID.rb.") do 67 | options[:dump] = "xmp-tmp.#{Process.pid}.rb" 68 | end 69 | on("--tmpfile", "--tempfile", "Use tmpfile instead of open3. (non-windows)") do 70 | options[:execute_ruby_tmpfile] = true 71 | end 72 | on("-w N", "--width N", Integer, "Set width of multi-line annotation. (xmpfilter only)") do |width| 73 | options[:width] = width 74 | end 75 | separator "" 76 | on("-h", "--help", "Show this message") do 77 | puts self 78 | exit 79 | end 80 | on("-v", "--version", "Show version information") do 81 | puts "#{File.basename($0)} #{XMPFilter::VERSION}" 82 | exit 83 | end 84 | end 85 | 86 | def auto_include_paths(include_paths, pwd) 87 | if pwd =~ %r!^(.+)/(lib|bin)! 88 | include_paths.unshift("#$1/lib").unshift("#$1/bin") 89 | elsif File.file? "#{pwd}/Rakefile" or File.file? "#{pwd}/rakefile" 90 | include_paths.unshift("#{pwd}/lib").unshift("#{pwd}/bin") 91 | end 92 | end 93 | module_function :auto_include_paths 94 | 95 | end 96 | 97 | def set_extra_opts(options) 98 | if idx = ARGV.index("--") 99 | options[:options] = ARGV[idx+1..-1] 100 | ARGV.replace ARGV[0...idx] 101 | else 102 | options[:options] = [] 103 | end 104 | end 105 | 106 | def check_opts(options) 107 | if options[:test_script] 108 | unless options[:filename] 109 | $stderr.puts "You must specify --filename as well as -t(--test)." 110 | exit 1 111 | end 112 | end 113 | end 114 | 115 | DEFAULT_OPTIONS = { 116 | :interpreter => "ruby", 117 | :options => ["hoge"], 118 | :min_codeline_size => 50, 119 | :width => 79, 120 | :libs => [], 121 | :evals => [], 122 | :include_paths => [], 123 | :dump => nil, 124 | :wd => nil, 125 | :warnings => true, 126 | :use_parentheses => true, 127 | :column => nil, 128 | :output_stdout => true, 129 | :test_script => nil, 130 | :test_method => nil, 131 | :detect_rct_fork => false, 132 | :use_rbtest => false, 133 | :detect_rbtest => false, 134 | :execute_ruby_tmpfile => false, 135 | } 136 | end # /Rcodetools 137 | -------------------------------------------------------------------------------- /lib/rcodetools/xmpfilter.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # Copyright (c) 2005-2008 Mauricio Fernandez http://eigenclass.org 3 | # rubikitch 4 | # Use and distribution subject to the terms of the Ruby license. 5 | 6 | # This is needed regexps cannot match with invalid-encoding strings. 7 | # xmpfilter is unaware of script encoding. 8 | Encoding.default_external = "ASCII-8BIT" if RUBY_VERSION >= "1.9" 9 | 10 | ENV['HOME'] ||= "#{ENV['HOMEDRIVE']}#{ENV['HOMEPATH']}" 11 | require 'rcodetools/fork_config' 12 | require 'rcodetools/compat' 13 | require 'tmpdir' 14 | 15 | module Rcodetools 16 | 17 | class XMPFilter 18 | VERSION = "0.8.5" 19 | 20 | MARKER = "!XMP#{Time.new.to_i}_#{Process.pid}_#{rand(1000000)}!" 21 | XMP_RE = Regexp.new("^" + Regexp.escape(MARKER) + '\[([0-9]+)\] (=>|~>|==>) (.*)') 22 | VAR = "_xmp_#{Time.new.to_i}_#{Process.pid}_#{rand(1000000)}" 23 | WARNING_RE = /.*:([0-9]+): warning: (.*)/ 24 | 25 | RuntimeData = Struct.new(:results, :exceptions, :bindings) 26 | 27 | INITIALIZE_OPTS = {:interpreter => "ruby", :options => [], :libs => [], 28 | :include_paths => [], :warnings => true, 29 | :use_parentheses => true} 30 | 31 | def windows? 32 | /win|mingw/ =~ RUBY_PLATFORM && /darwin/ !~ RUBY_PLATFORM 33 | end 34 | 35 | Interpreter = Struct.new(:options, :execute_method, :accept_debug, :accept_include_paths, :chdir_proc) 36 | INTERPRETER_RUBY = Interpreter.new(["-w"], 37 | :execute_ruby, true, true, nil) 38 | INTERPRETER_RBTEST = Interpreter.new(["-S", "rbtest"], 39 | :execute_script, false, false, nil) 40 | INTERPRETER_FORK = Interpreter.new(["-S", "rct-fork-client"], 41 | :execute_tmpfile, false, true, 42 | lambda { Fork::chdir_fork_directory }) 43 | 44 | def self.detect_rbtest(code, opts) 45 | opts[:use_rbtest] ||= (opts[:detect_rbtest] and code =~ /^=begin test./) ? true : false 46 | end 47 | 48 | # The processor (overridable) 49 | def self.run(code, opts) 50 | new(opts).annotate(code) 51 | end 52 | 53 | def initialize(opts = {}) 54 | options = INITIALIZE_OPTS.merge opts 55 | @interpreter_info = INTERPRETER_RUBY 56 | @interpreter = options[:interpreter] 57 | @options = options[:options] 58 | @libs = options[:libs] 59 | @evals = options[:evals] || [] 60 | @include_paths = options[:include_paths] 61 | @output_stdout = options[:output_stdout] 62 | @dump = options[:dump] 63 | @warnings = options[:warnings] 64 | @parentheses = options[:use_parentheses] 65 | @ignore_NoMethodError = options[:ignore_NoMethodError] 66 | test_script = options[:test_script] 67 | test_method = options[:test_method] 68 | filename = options[:filename] 69 | @execute_ruby_tmpfile = options[:execute_ruby_tmpfile] 70 | @postfix = "" 71 | @stdin_path = nil 72 | @width = options[:width] 73 | 74 | initialize_rct_fork if options[:detect_rct_fork] 75 | initialize_rbtest if options[:use_rbtest] 76 | initialize_for_test_script test_script, test_method, filename if test_script and !options[:use_rbtest] 77 | end 78 | 79 | def initialize_rct_fork 80 | if Fork::run? 81 | @interpreter_info = INTERPRETER_FORK 82 | end 83 | end 84 | 85 | def initialize_rbtest 86 | @interpreter_info = INTERPRETER_RBTEST 87 | end 88 | 89 | def initialize_for_test_script(test_script, test_method, filename) 90 | test_script.replace File.expand_path(test_script) 91 | filename.replace File.expand_path(filename) 92 | unless test_script == filename 93 | basedir = common_path(test_script, filename) 94 | relative_filename = filename[basedir.length+1 .. -1].sub(%r!^lib/!, '') 95 | @evals << %Q!$LOADED_FEATURES << #{relative_filename.dump}! 96 | @evals << safe_require_code('test/unit') 97 | @evals << %Q!load #{test_script.dump}! 98 | end 99 | test_method = get_test_method_from_lineno(test_script, test_method.to_i) if test_method =~ /^\d/ 100 | @evals << %Q!Test::Unit::AutoRunner.run(false, nil, ["-n", #{test_method.dump}])! if test_method 101 | end 102 | 103 | def get_test_method_from_lineno(filename, lineno) 104 | lines = File.readlines(filename) 105 | (lineno-1).downto(0) do |i| 106 | if lines[i] =~ /^ *def *(test_[A-Za-z0-9?!_]+)$/ 107 | return $1 108 | end 109 | end 110 | nil 111 | end 112 | 113 | def common_path(a, b) 114 | (a.split(File::Separator) & b.split(File::Separator)).join(File::Separator) 115 | end 116 | 117 | def add_markers(code, min_codeline_size = 50) 118 | maxlen = code.map{|x| x.size}.max 119 | maxlen = [min_codeline_size, maxlen + 2].max 120 | ret = "" 121 | code.each do |l| 122 | l = l.chomp.gsub(/ # (=>|!>).*/, "").gsub(/\s*$/, "") 123 | ret << (l + " " * (maxlen - l.size) + " # =>\n") 124 | end 125 | ret 126 | end 127 | 128 | SINGLE_LINE_RE = /^(?!(?:\s+|(?:\s*#.+)?)# ?=>)(.*) # ?=>.*/ 129 | MULTI_LINE_RE = /^(.*)\n(( *)# ?=>.*(?:\n|\z))(?: *# .*\n)*/ 130 | def annotate(code) 131 | idx = 0 132 | code = code.gsub(/ # !>.*/, '') 133 | newcode = code.gsub(SINGLE_LINE_RE){ prepare_line($1, idx += 1) } 134 | newcode.gsub!(MULTI_LINE_RE){ prepare_line($1, idx += 1, true)} 135 | File.open(@dump, "w"){|f| f.puts newcode} if @dump 136 | stdout, stderr = execute(newcode) 137 | output = stderr.readlines 138 | runtime_data = extract_data(output) 139 | idx = 0 140 | annotated = code.gsub(SINGLE_LINE_RE) { |l| 141 | expr = $1 142 | if /^\s*#/ =~ l 143 | l 144 | else 145 | annotated_line(l, expr, runtime_data, idx += 1) 146 | end 147 | } 148 | annotated.gsub!(/ # !>.*/, '') 149 | annotated.gsub!(/# (>>|~>)[^\n]*\n/m, ""); 150 | annotated.gsub!(MULTI_LINE_RE) { |l| 151 | annotated_multi_line(l, $1, $3, runtime_data, idx += 1) 152 | } 153 | ret = final_decoration(annotated, output) 154 | if @output_stdout and (s = stdout.read) != "" 155 | ret << s.inject(""){|s,line| s + "# >> #{line}".chomp + "\n" } 156 | end 157 | ret 158 | end 159 | 160 | def annotated_line(line, expression, runtime_data, idx) 161 | "#{expression} # => " + (runtime_data.results[idx].map{|x| x[1]} || []).join(", ") 162 | end 163 | 164 | def annotated_multi_line(line, expression, indent, runtime_data, idx) 165 | pretty = (runtime_data.results[idx].map{|x| x[1]} || []).join(", ") 166 | first, *rest = pretty.to_a 167 | rest.inject("#{expression}\n#{indent}# => #{first || "\n"}") {|s, l| s << "#{indent}# " << l } 168 | end 169 | 170 | def prepare_line_annotation(expr, idx, multi_line=false) 171 | v = "#{VAR}" 172 | blocal = "__#{VAR}" 173 | blocal2 = "___#{VAR}" 174 | lastmatch = "____#{VAR}" 175 | if multi_line 176 | pp = safe_require_code "pp" 177 | result = "((begin; #{lastmatch} = $~; PP.pp(#{v}, '', #{@width-5}).gsub(/\\r?\\n/, 'PPPROTECT'); ensure; $~ = #{lastmatch} end))" 178 | else 179 | pp = '' 180 | result = "#{v}.inspect" 181 | end 182 | oneline_ize(<<-EOF).chomp 183 | #{pp} 184 | #{v} = (#{expr}) 185 | $stderr.puts("#{MARKER}[#{idx}] => " + #{v}.class.to_s + " " + #{result}) || begin 186 | $stderr.puts local_variables 187 | local_variables.each{|#{blocal}| 188 | #{blocal2} = eval(#{blocal}) 189 | if #{v} == #{blocal2} && #{blocal} != %#{expr}.strip 190 | $stderr.puts("#{MARKER}[#{idx}] ==> " + #{blocal}) 191 | elsif [#{blocal2}] == #{v} 192 | $stderr.puts("#{MARKER}[#{idx}] ==> [" + #{blocal} + "]") 193 | end 194 | } 195 | nil 196 | rescue Exception 197 | nil 198 | end || #{v} 199 | EOF 200 | 201 | end 202 | alias_method :prepare_line, :prepare_line_annotation 203 | 204 | def safe_require_code(lib) 205 | oldverbose = "$#{VAR}_old_verbose" 206 | "#{oldverbose} = $VERBOSE; $VERBOSE = false; require '#{lib}'; $VERBOSE = #{oldverbose}" 207 | end 208 | private :safe_require_code 209 | 210 | def execute_ruby(code) 211 | meth = (windows? or @execute_ruby_tmpfile) ? :execute_tmpfile : :execute_popen 212 | __send__ meth, code 213 | end 214 | 215 | def execute_tmpfile(code) 216 | ios = %w[_ stdin stdout stderr] 217 | stdin, stdout, stderr = (1..3).map do |i| 218 | fname = if $DEBUG 219 | "xmpfilter.tmpfile_#{ios[i]}.rb" 220 | else 221 | "xmpfilter.tmpfile_#{Process.pid}-#{i}.rb" 222 | end 223 | f = File.open(fname, "w+") 224 | at_exit { f.close unless f.closed?; File.unlink fname unless $DEBUG} 225 | f 226 | end 227 | stdin.puts code 228 | stdin.close 229 | @stdin_path = File.expand_path stdin.path 230 | exe_line = <<-EOF.map{|l| l.strip}.join(";") 231 | $stdout.reopen('#{File.expand_path(stdout.path)}', 'w') 232 | $stderr.reopen('#{File.expand_path(stderr.path)}', 'w') 233 | $0 = '#{File.expand_path(stdin.path)}' 234 | ARGV.replace(#{@options.inspect}) 235 | load #{File.expand_path(stdin.path).inspect} 236 | #{@evals.join(";")} 237 | EOF 238 | debugprint "execute command = #{(interpreter_command << "-e" << exe_line).join ' '}" 239 | 240 | oldpwd = Dir.pwd 241 | @interpreter_info.chdir_proc and @interpreter_info.chdir_proc.call 242 | system(*(interpreter_command << "-e" << exe_line)) 243 | Dir.chdir oldpwd 244 | [stdout, stderr] 245 | end 246 | 247 | def execute_popen(code) 248 | require 'open3' 249 | stdin, stdout, stderr = Open3::popen3(*interpreter_command) 250 | stdin.puts code 251 | @evals.each{|x| stdin.puts x } unless @evals.empty? 252 | stdin.close 253 | [stdout, stderr] 254 | end 255 | 256 | def execute_script(code) 257 | path = File.expand_path("xmpfilter.tmpfile_#{Process.pid}.rb", Dir.tmpdir) 258 | File.open(path, "w"){|f| f.puts code} 259 | at_exit { File.unlink path if File.exist? path} 260 | stdout_path, stderr_path = (1..2).map do |i| 261 | fname = "xmpfilter.tmpfile_#{Process.pid}-#{i}.rb" 262 | File.expand_path(fname, Dir.tmpdir) 263 | end 264 | args = *(interpreter_command << %["#{path}"] << "2>" << 265 | %["#{stderr_path}"] << ">" << %["#{stdout_path}"]) 266 | system(args.join(" ")) 267 | 268 | [stdout_path, stderr_path].map do |fullname| 269 | f = File.open(fullname, "r") 270 | at_exit { 271 | f.close unless f.closed? 272 | File.unlink fullname if File.exist? fullname 273 | } 274 | f 275 | end 276 | end 277 | 278 | def execute(code) 279 | __send__ @interpreter_info.execute_method, code 280 | end 281 | 282 | def interpreter_command 283 | r = [ @interpreter ] + @interpreter_info.options 284 | r << "-d" if $DEBUG and @interpreter_info.accept_debug 285 | r << "-I#{@include_paths.join(":")}" if @interpreter_info.accept_include_paths and !@include_paths.empty? 286 | @libs.each{|x| r << "-r#{x}" } unless @libs.empty? 287 | (r << "-").concat @options unless @options.empty? 288 | r 289 | end 290 | 291 | def extract_data(output) 292 | results = Hash.new{|h,k| h[k] = []} 293 | exceptions = Hash.new{|h,k| h[k] = []} 294 | bindings = Hash.new{|h,k| h[k] = []} 295 | output.grep(XMP_RE).each do |line| 296 | result_id, op, result = XMP_RE.match(line).captures 297 | case op 298 | when "=>" 299 | klass, value = /(\S+)\s+(.*)/.match(result).captures 300 | results[result_id.to_i] << [klass, value.gsub(/PPPROTECT/, "\n")] 301 | when "~>" 302 | exceptions[result_id.to_i] << result 303 | when "==>" 304 | bindings[result_id.to_i] << result unless result.index(VAR) 305 | end 306 | end 307 | RuntimeData.new(results, exceptions, bindings) 308 | end 309 | 310 | def final_decoration(code, output) 311 | warnings = {} 312 | output.join.grep(WARNING_RE).map do |x| 313 | md = WARNING_RE.match(x) 314 | warnings[md[1].to_i] = md[2] 315 | end 316 | idx = 0 317 | ret = code.map do |line| 318 | w = warnings[idx+=1] 319 | if @warnings 320 | w ? (line.chomp + " # !> #{w}") : line 321 | else 322 | line 323 | end 324 | end 325 | output = output.reject{|x| /^-:[0-9]+: warning/.match(x)} 326 | if exception = /^-e?:[0-9]+:.*|^(?!!XMP)[^\n]+:[0-9]+:in .*/m.match(output.join) 327 | err = exception[0] 328 | err.gsub!(Regexp.union(@stdin_path), '-') if @stdin_path 329 | ret << err.map{|line| "# ~> " + line } 330 | end 331 | ret 332 | end 333 | 334 | def oneline_ize(code) 335 | "((" + code.gsub(/\r?\n|\r/, ';') + "));#{@postfix}\n" 336 | end 337 | 338 | def debugprint(*args) 339 | $stderr.puts(*args) if $DEBUG 340 | end 341 | end # clas XMPFilter 342 | 343 | class XMPAddMarkers < XMPFilter 344 | def self.run(code, opts) 345 | new(opts).add_markers(code, opts[:min_codeline_size]) 346 | end 347 | end 348 | 349 | end 350 | -------------------------------------------------------------------------------- /lib/rcodetools/xmptestunitfilter.rb: -------------------------------------------------------------------------------- 1 | require 'rcodetools/xmpfilter' 2 | 3 | module Rcodetools 4 | 5 | FLOAT_TOLERANCE = 0.0001 6 | class XMPTestUnitFilter < XMPFilter 7 | def initialize(opts = {}) 8 | super 9 | @output_stdout = false 10 | mod = @parentheses ? :WithParentheses : :Poetry 11 | extend self.class.const_get(mod) unless opts[:_no_extend_module] 12 | end 13 | 14 | private 15 | def annotated_line(line, expression, runtime_data, idx) 16 | indent = /^\s*/.match(line)[0] 17 | assertions(expression.strip, runtime_data, idx).map{|x| indent + x}.join("\n") 18 | end 19 | 20 | def prepare_line(expr, idx) 21 | basic_eval = prepare_line_annotation(expr, idx) 22 | %|begin; #{basic_eval}; rescue Exception; $stderr.puts("#{MARKER}[#{idx}] ~> " + $!.class.to_s); end| 23 | end 24 | 25 | def assertions(expression, runtime_data, index) 26 | exceptions = runtime_data.exceptions 27 | ret = [] 28 | 29 | unless (vars = runtime_data.bindings[index]).empty? 30 | vars.each{|var| ret << equal_assertion(var, expression) } 31 | end 32 | if !(wanted = runtime_data.results[index]).empty? || !exceptions[index] 33 | case (wanted[0][1] rescue 1) 34 | when "nil" 35 | ret.concat nil_assertion(expression) 36 | else 37 | case wanted.size 38 | when 1 39 | ret.concat _value_assertions(wanted[0], expression) 40 | else 41 | # discard values from multiple runs 42 | ret.concat(["#xmpfilter: WARNING!! extra values ignored"] + 43 | _value_assertions(wanted[0], expression)) 44 | end 45 | end 46 | else 47 | ret.concat raise_assertion(expression, exceptions, index) 48 | end 49 | 50 | ret 51 | end 52 | 53 | OTHER = Class.new 54 | def _value_assertions(klass_value_txt_pair, expression) 55 | klass_txt, value_txt = klass_value_txt_pair 56 | value = eval(value_txt) || OTHER.new 57 | # special cases 58 | value = nil if value_txt.strip == "nil" 59 | value = false if value_txt.strip == "false" 60 | value_assertions klass_txt, value_txt, value, expression 61 | rescue Exception 62 | return object_assertions(klass_txt, value_txt, expression) 63 | end 64 | 65 | def raise_assertion(expression, exceptions, index) 66 | ["assert_raise(#{exceptions[index][0]}){#{expression}}"] 67 | end 68 | 69 | module WithParentheses 70 | def nil_assertion(expression) 71 | ["assert_nil(#{expression})"] 72 | end 73 | 74 | def value_assertions(klass_txt, value_txt, value, expression) 75 | case value 76 | when Float 77 | ["assert_in_delta(#{value.inspect}, #{expression}, #{FLOAT_TOLERANCE})"] 78 | when Numeric, String, Hash, Array, Regexp, TrueClass, FalseClass, Symbol, NilClass 79 | ["assert_equal(#{value_txt}, #{expression})"] 80 | else 81 | object_assertions(klass_txt, value_txt, expression) 82 | end 83 | end 84 | 85 | def object_assertions(klass_txt, value_txt, expression) 86 | [ "assert_kind_of(#{klass_txt}, #{expression})", 87 | "assert_equal(#{value_txt.inspect}, #{expression}.inspect)" ] 88 | end 89 | 90 | def equal_assertion(expected, actual) 91 | "assert_equal(#{expected}, #{actual})" 92 | end 93 | end 94 | 95 | module Poetry 96 | def nil_assertion(expression) 97 | ["assert_nil #{expression}"] 98 | end 99 | 100 | def value_assertions(klass_txt, value_txt, value, expression) 101 | case value 102 | when Float 103 | ["assert_in_delta #{value.inspect}, #{expression}, #{FLOAT_TOLERANCE}"] 104 | when Numeric, String, Hash, Array, Regexp, TrueClass, FalseClass, Symbol, NilClass 105 | ["assert_equal #{value_txt}, #{expression}"] 106 | else 107 | object_assertions klass_txt, value_txt, expression 108 | end 109 | end 110 | 111 | def object_assertions(klass_txt, value_txt, expression) 112 | [ "assert_kind_of #{klass_txt}, #{expression} ", 113 | "assert_equal #{value_txt.inspect}, #{expression}.inspect" ] 114 | end 115 | 116 | def equal_assertion(expected, actual) 117 | "assert_equal #{expected}, #{actual}" 118 | end 119 | end 120 | end 121 | 122 | class XMPRSpecFilter < XMPTestUnitFilter 123 | def initialize(x={}) 124 | super(x.merge(:_no_extend_module => true)) 125 | load_rspec 126 | specver = (Spec::VERSION::STRING rescue "1.0.0") 127 | api_module = specver >= "0.8.0" ? NewAPI : OldAPI 128 | mod = @parentheses ? :WithParentheses : :Poetry 129 | extend api_module.const_get(mod) 130 | extend api_module 131 | end 132 | 133 | private 134 | def load_rspec 135 | begin 136 | require 'spec/version' 137 | rescue LoadError 138 | require 'rubygems' 139 | begin 140 | require 'spec/version' 141 | rescue LoadError # if rspec isn't available, use most recent conventions 142 | end 143 | end 144 | end 145 | 146 | alias :execute :execute_script 147 | 148 | def interpreter_command 149 | [@interpreter] + @libs.map{|x| "-r#{x}"} 150 | end 151 | 152 | module NewAPI 153 | def raise_assertion(expression, exceptions, index) 154 | ["lambda{#{expression}}.should raise_error(#{exceptions[index][0]})"] 155 | end 156 | 157 | module WithParentheses 158 | def nil_assertion(expression) 159 | ["(#{expression}).should be_nil"] 160 | end 161 | 162 | def value_assertions(klass_txt, value_txt, value, expression) 163 | case value 164 | when Float 165 | ["(#{expression}).should be_close(#{value.inspect}, #{FLOAT_TOLERANCE})"] 166 | when Numeric, String, Hash, Array, Regexp, TrueClass, FalseClass, Symbol, NilClass 167 | ["(#{expression}).should == (#{value_txt})"] 168 | else 169 | object_assertions klass_txt, value_txt, expression 170 | end 171 | end 172 | 173 | def object_assertions(klass_txt, value_txt, expression) 174 | [ "(#{expression}).should be_a_kind_of(#{klass_txt})", 175 | "(#{expression}.inspect).should == (#{value_txt.inspect})" ] 176 | end 177 | 178 | def equal_assertion(expected, actual) 179 | "(#{actual}).should == (#{expected})" 180 | end 181 | end 182 | 183 | module Poetry 184 | def nil_assertion(expression) 185 | ["#{expression}.should be_nil"] 186 | end 187 | 188 | def value_assertions(klass_txt, value_txt, value, expression) 189 | case value 190 | when Float 191 | ["#{expression}.should be_close(#{value.inspect}, #{FLOAT_TOLERANCE})"] 192 | when Numeric, String, Hash, Array, Regexp, TrueClass, FalseClass, Symbol, NilClass 193 | ["#{expression}.should == #{value_txt}"] 194 | else 195 | object_assertions klass_txt, value_txt, expression 196 | end 197 | end 198 | 199 | def object_assertions(klass_txt, value_txt, expression) 200 | [ "#{expression}.should be_a_kind_of(#{klass_txt})", 201 | "#{expression}.inspect.should == #{value_txt.inspect}" ] 202 | end 203 | 204 | def equal_assertion(expected, actual) 205 | "#{actual}.should == #{expected}" 206 | end 207 | end 208 | end 209 | 210 | module OldAPI 211 | # old rspec, use deprecated syntax 212 | def raise_assertion(expression, exceptions, index) 213 | ["lambda{#{expression}}.should_raise_error(#{exceptions[index][0]})"] 214 | end 215 | 216 | module WithParentheses 217 | def nil_assertion(expression) 218 | ["(#{expression}).should_be_nil"] 219 | end 220 | 221 | def value_assertions(klass_txt, value_txt, value, expression) 222 | case value 223 | when Float 224 | ["(#{expression}).should_be_close(#{value.inspect}, #{FLOAT_TOLERANCE})"] 225 | when Numeric, String, Hash, Array, Regexp, TrueClass, FalseClass, Symbol, NilClass 226 | ["(#{expression}).should_equal(#{value_txt})"] 227 | else 228 | object_assertions klass_txt, value_txt, expression 229 | end 230 | end 231 | 232 | def object_assertions(klass_txt, value_txt, expression) 233 | [ "(#{expression}).should_be_a_kind_of(#{klass_txt})", 234 | "(#{expression}.inspect).should_equal(#{value_txt.inspect})" ] 235 | end 236 | 237 | def equal_assertion(expected, actual) 238 | "(#{actual}).should_equal(#{expected})" 239 | end 240 | end 241 | 242 | module Poetry 243 | def nil_assertion(expression) 244 | ["#{expression}.should_be_nil"] 245 | end 246 | 247 | def value_assertions(klass_txt, value_txt, value, expression) 248 | case value 249 | when Float 250 | ["#{expression}.should_be_close #{value.inspect}, #{FLOAT_TOLERANCE}"] 251 | when Numeric, String, Hash, Array, Regexp, TrueClass, FalseClass, Symbol, NilClass 252 | ["#{expression}.should_equal #{value_txt}"] 253 | else 254 | object_assertions klass_txt, value_txt, expression 255 | end 256 | end 257 | 258 | def object_assertions(klass_txt, value_txt, expression) 259 | [ "#{expression}.should_be_a_kind_of #{klass_txt}", 260 | "#{expression}.inspect.should_equal #{value_txt.inspect}" ] 261 | end 262 | 263 | def equal_assertion(expected, actual) 264 | "#{actual}.should_equal #{expected}" 265 | end 266 | end 267 | end 268 | 269 | 270 | end 271 | 272 | class XMPExpectationsFilter < XMPTestUnitFilter 273 | def initialize(x={}) 274 | super(x.merge(:_no_extend_module => true)) 275 | @warnings = false 276 | end 277 | 278 | def expectation(expected, actual) 279 | < 'unit', 'controllers' => 'functional' } 44 | RAILS_TESTNAME2MVC = RAILS_MVC2TESTNAME.invert 45 | def test_file_00_rails(implementation, basedir, dir, node) # rails 46 | if m = %r!app/(models|controllers)/(.+)\.rb$!.match(implementation) 47 | "%stest/%s/%s_test.rb" % [ m.pre_match, RAILS_MVC2TESTNAME[m[1]], m[2] ] 48 | end 49 | end 50 | 51 | def test_file_05_rails_lib(implementation, basedir, dir, node) 52 | if basedir and File.directory?( File.join(basedir, "app") ) 53 | "#{basedir}test/unit/test_#{node}.rb" 54 | end 55 | end 56 | 57 | def test_file_10_no_match(implementation, basedir, dir, node) 58 | if [basedir, dir, node].all?{|x| x.nil?} 59 | "#{File.dirname(implementation)}/test_#{File.basename(implementation)}" 60 | end 61 | end 62 | 63 | def test_file_20_simple(implementation, basedir, dir, node) # test/test_NODE.rb 64 | exist "#{basedir}test/test_#{node}.rb" 65 | end 66 | 67 | def test_file_30_flat(implementation, basedir, dir, node) # lib/XXX/NODE.rb -> test/test_NODE.rb 68 | exist "#{basedir}test/test_#{node}.rb" if dir 69 | end 70 | 71 | def test_file_99_autotest_default(implementation, basedir, dir, node) # lib/XXX/NODE.rb -> test/XXX/test_NODE.rb 72 | "#{basedir}test/#{dir}test_#{node}.rb" 73 | end 74 | 75 | def implementation_file_00_rails(test, basedir, dir, node) 76 | if m = %r!test/(unit|functional)/(.+)_test.rb$!.match(test) 77 | "%sapp/%s/%s.rb" % [ m.pre_match, RAILS_TESTNAME2MVC[m[1]], m[2] ] 78 | end 79 | end 80 | 81 | def implementation_file_10_no_match(test, basename, dir, node) 82 | if dir == nil and node == nil and test =~ %r!/test_(.+)\.rb$! 83 | test.sub("/test_", "/") 84 | end 85 | end 86 | 87 | def implementation_file_20(test, basedir, dir, node) 88 | exist("#{basedir}lib/#{dir}#{node}.rb") 89 | end 90 | 91 | def implementation_file_30_flat(test, basedir, dir, node) 92 | Dir[ "#{basedir}lib/**/#{node}.rb" ].first 93 | end 94 | 95 | def implementation_file_99_default(test, basedir, dir, node) 96 | "#{basedir}lib/#{dir}#{node}.rb" 97 | end 98 | 99 | end 100 | -------------------------------------------------------------------------------- /rcodetools.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JoshCheek/rcodetools/0d0c448fe3bf3f2b2a51d89a2ff387e0c1c7da7c/rcodetools.gif -------------------------------------------------------------------------------- /rcodetools.sxmp: -------------------------------------------------------------------------------- 1 | $ ruby='ruby -Ilib ' 2 | $ export path=~/rcodetools/bin:$PATH 3 | $ echo '1.objec' | ruby -d -S rct-complete --dev --completion-emacs-icicles --line=1 4 | expr_orig=1.objec 5 | expr(sliced)=1.objec 6 | aref_or_aset=nil 7 | expr(before set_last_word)=1.objec 8 | expr(strip opchars)=1.objec 9 | expr.eval_string=1 10 | expr.meth=objec 11 | expr(after set_last_word)=1.objec 12 | expr(processed)=1.objec 13 | newcode 14 | ((_xmp_1177764661_24372_531875_recv = (1) 15 | _xmp_1177764661_24372_531875 = (((1).methods(true)).map{|m| "#{m}\0" + (( _xmp_1177764661_24372_531875_result = 1.method(m).inspect.match( %r[\A#<(?:Unbound)?Method: (.*?)>\Z] )[1].sub(/\A.*?\((.*?)\)(.*)\Z/){ "#{$1}#{$2}" }.sub(/##/) { "#{$1}." } 16 | _xmp_1177764661_24372_531875_result = 1.to_s + ".new" if _xmp_1177764661_24372_531875_result == 'Class#new' and 1.private_method_defined?(:initialize) 17 | _xmp_1177764661_24372_531875_result = "Object#" + m if _xmp_1177764661_24372_531875_result =~ /^Kernel#/ and Kernel.instance_methods(false).include? m 18 | _xmp_1177764661_24372_531875_result 19 | )) 20 | }).grep(/^objec/) 21 | _xmp_1177764661_24372_531875_recv = Module === _xmp_1177764661_24372_531875_recv ? _xmp_1177764661_24372_531875_recv : _xmp_1177764661_24372_531875_recv.class 22 | $stderr.puts("!XMP1177764661_24372_198701![1] => " + _xmp_1177764661_24372_531875_recv.to_s + " " + _xmp_1177764661_24372_531875.join(" ")) || _xmp_1177764661_24372_531875 23 | exit 24 | )) 25 | -------------------------------------------------------------------------------- 26 | stderr 27 | !XMP1177764661_24372_198701![1] => Fixnum object_idObject#object_id 28 | -------------------------------------------------------------------------------- 29 | dat = ["Fixnum", "object_id\000Object#object_id"] 30 | (progn 31 | (setq rct-method-completion-table '(("object_id\t[Object#object_id]") )) 32 | (setq alist '(("object_id" . "Object#object_id"))) 33 | (setq pattern "objec") 34 | (setq klass "Fixnum") 35 | ) 36 | $ ruby -d -S rct-complete --dev --completion-emacs-icicles -S rct-fork-client --line=2 --column=2 /tmp/rs.rb 37 | expr_orig=fo 38 | expr(sliced)=fo 39 | aref_or_aset=nil 40 | expr(before set_last_word)=fo 41 | expr(strip opchars)=fo 42 | expr.eval_string= 43 | expr.meth= 44 | expr(after set_last_word)=fo 45 | expr(processed)=fo 46 | newcode 47 | require 'foo' 48 | ((_xmp_1177764661_24376_874435_recv = (self) 49 | _xmp_1177764661_24376_874435 = ((methods | private_methods).map{|m| "#{m}\0" + (( _xmp_1177764661_24376_874435_result = self.method(m).inspect.match( %r[\A#<(?:Unbound)?Method: (.*?)>\Z] )[1].sub(/\A.*?\((.*?)\)(.*)\Z/){ "#{$1}#{$2}" }.sub(/##/) { "#{$1}." } 50 | _xmp_1177764661_24376_874435_result = self.to_s + ".new" if _xmp_1177764661_24376_874435_result == 'Class#new' and self.private_method_defined?(:initialize) 51 | _xmp_1177764661_24376_874435_result = "Object#" + m if _xmp_1177764661_24376_874435_result =~ /^Kernel#/ and Kernel.instance_methods(false).include? m 52 | _xmp_1177764661_24376_874435_result 53 | )) 54 | } + local_variables | self.class.constants).grep(/^fo/) 55 | _xmp_1177764661_24376_874435_recv = Module === _xmp_1177764661_24376_874435_recv ? _xmp_1177764661_24376_874435_recv : _xmp_1177764661_24376_874435_recv.class 56 | $stderr.puts("!XMP1177764661_24376_375351![1] => " + _xmp_1177764661_24376_874435_recv.to_s + " " + _xmp_1177764661_24376_874435.join(" ")) || _xmp_1177764661_24376_874435 57 | exit 58 | )) 59 | -------------------------------------------------------------------------------- 60 | execute command = rct-fork-client -I/m/home/rubikitch/src/rcodetools/bin:/m/home/rubikitch/src/rcodetools/lib -e $stdout.reopen('/m/home/rubikitch/src/rcodetools/xmpfilter.tmpfile_stdout.rb', 'w');$stderr.reopen('/m/home/rubikitch/src/rcodetools/xmpfilter.tmpfile_stderr.rb', 'w');$0.replace '/m/home/rubikitch/src/rcodetools/xmpfilter.tmpfile_stdin.rb';ARGV.replace([]);load "/m/home/rubikitch/src/rcodetools/xmpfilter.tmpfile_stdin.rb"; 61 | stderr 62 | !XMP1177764661_24376_375351![1] => Object fooObject#foo forkKernel#fork formatKernel#format 63 | -------------------------------------------------------------------------------- 64 | dat = ["Object", "foo\000Object#foo fork\000Kernel#fork format\000Kernel#format"] 65 | (progn 66 | (setq rct-method-completion-table '(("foo\t[Object#foo]") ("fork\t[Kernel#fork]") ("format\t[Kernel#format]") )) 67 | (setq alist '(("foo" . "Object#foo")("fork" . "Kernel#fork")("format" . "Kernel#format"))) 68 | (setq pattern "fo") 69 | (setq klass "Object") 70 | ) 71 | $ ruby -S rct-complete --dev --completion-emacs-icicles -S rct-fork-client --line=2 --column=2 /tmp/rs.rb 72 | (progn 73 | (setq rct-method-completion-table '(("foo\t[Object#foo]") ("fork\t[Kernel#fork]") ("format\t[Kernel#format]") )) 74 | (setq alist '(("foo" . "Object#foo")("fork" . "Kernel#fork")("format" . "Kernel#format"))) 75 | (setq pattern "fo") 76 | (setq klass "Object") 77 | ) 78 | $ #cd ~/ruby; ruby -S rct-complete --dev --completion-emacs-icicles -S rct-fork-client --line=2 --column=2 /tmp/rs.rb 79 | $ # cd ~/ruby; ruby -d -S rct-complete --dev --completion-emacs-icicles -S rct-fork-client --line=2 --column=2 /tmp/rs.rb 80 | -------------------------------------------------------------------------------- /rcodetools.vim: -------------------------------------------------------------------------------- 1 | " Copyright (C) 2006 Mauricio Fernandez 2 | " rcodetools support plugin 3 | " 4 | 5 | if exists("loaded_rcodetools") 6 | finish 7 | endif 8 | 9 | let loaded_rcodetools = 1 10 | let s:save_cpo = &cpo 11 | set cpo&vim 12 | 13 | "{{{ set s:sid 14 | 15 | map xx xx 16 | let s:sid = maparg("xx") 17 | unmap xx 18 | let s:sid = substitute(s:sid, 'xx', '', '') 19 | 20 | "{{{ function: s:spellgetoption(name, default) 21 | " grab a user-specified option to override the default provided. options are 22 | " searched in the window, buffer, then global spaces. 23 | function! s:GetOption(name, default) 24 | if exists("w:{&filetype}_" . a:name) 25 | execute "return w:{&filetype}_".a:name 26 | elseif exists("w:" . a:name) 27 | execute "return w:".a:name 28 | elseif exists("b:{&filetype}_" . a:name) 29 | execute "return b:{&filetype}_".a:name 30 | elseif exists("b:" . a:name) 31 | execute "return b:".a:name 32 | elseif exists("g:{&filetype}_" . a:name) 33 | execute "return g:{&filetype}_".a:name 34 | elseif exists("g:" . a:name) 35 | execute "return g:".a:name 36 | else 37 | return a:default 38 | endif 39 | endfunction 40 | 41 | "{{{ IsOptionSet 42 | function! s:IsOptionSet(name) 43 | let bogus_val = "df hdsoi3y98 hjsdfhdkj" 44 | return s:GetOption(a:name, bogus_val) == bogus_val ? 0 : 1 45 | endfunction 46 | 47 | 48 | "{{{ RCT_completion function 49 | 50 | let s:last_test_file = "" 51 | let s:last_test_lineno = 0 52 | 53 | let s:rct_completion_col = 0 54 | let s:rct_tmpfile = "" 55 | 56 | function! RCT_command_with_test_options(cmd) 57 | if s:last_test_file != "" 58 | return a:cmd . 59 | \ "-" . "-filename='" . expand("%:p") . "' " . 60 | \ "-t '" . s:last_test_file . "@" . s:last_test_lineno . "' " 61 | endif 62 | return a:cmd 63 | endfunction 64 | 65 | function! RCT_completion(findstart, base) 66 | if a:findstart 67 | let s:rct_completion_col = col('.') - 1 68 | let s:rct_tmpfile = "tmp-rcodetools" . strftime("Y-%m-%d-%H-%M-%S.rb") 69 | silent exec ":w " . s:rct_tmpfile 70 | return strridx(getline('.'), '.', col('.')) + 1 71 | else 72 | let line = line('.') 73 | let column = s:rct_completion_col 74 | 75 | let command = "rct-complete --completion-class-info --dev --fork --line=" . 76 | \ line . " --column=" . column . " " 77 | let command = RCT_command_with_test_options(command) . s:rct_tmpfile 78 | 79 | let data = split(system(command), '\n') 80 | 81 | for dline in data 82 | let parts = split(dline, "\t") 83 | let name = get(parts, 0) 84 | let selector = get(parts, 1) 85 | echo name 86 | echo selector 87 | if s:GetOption('rct_completion_use_fri', 0) && s:GetOption('rct_completion_info_max_len', 20) >= len(data) 88 | let fri_data = system('fri -f plain ' . "'" . selector . "'" . ' 2>/dev/null') 89 | call complete_add({'word': name, 90 | \ 'menu': get(split(fri_data), 2, ''), 91 | \ 'info': fri_data } ) 92 | else 93 | call complete_add(name) 94 | endif 95 | if complete_check() 96 | break 97 | endif 98 | endfor 99 | 100 | call delete(s:rct_tmpfile) 101 | return [] 102 | endif 103 | endfunction 104 | 105 | "{{{ ri functions 106 | 107 | function! RCT_new_ri_window() 108 | execute "new" 109 | execute "set bufhidden=delete buftype=nofile noswapfile nobuflisted" 110 | execute 'nmap 2u' 111 | execute 'nmap :call' . s:sid . 'RCT_execute_ri(expand(""))' 112 | endfunction 113 | 114 | function! RCT_execute_ri(query_term) 115 | silent %delete _ 116 | let term = matchstr(a:query_term, '\v[^,.;]+') 117 | let cmd = s:GetOption("RCT_ri_cmd", "fri -f plain ") 118 | let text = system(cmd . "'" . term . "'") 119 | call append(0, split(text, "\n")) 120 | normal gg 121 | endfunction 122 | 123 | function! RCT_find_tag_or_ri(fullname) 124 | " rubikitch: modified for rtags-compatible tags 125 | let tagname = '::' . a:fullname 126 | let tagresults = taglist(tagname) 127 | if len(tagresults) != 0 128 | execute "tjump " . tagname 129 | else 130 | call RCT_new_ri_window() 131 | call RCT_execute_ri(a:fullname) 132 | endif 133 | endfunction 134 | 135 | function! RCT_smart_ri() 136 | let tmpfile = "tmp-rcodetools" . strftime("Y-%m-%d-%H-%M-%S.rb") 137 | silent exec ":w " . tmpfile 138 | 139 | let line = line('.') 140 | let column = col('.') - 1 141 | let command = "rct-doc --ri-vim --line=" . line . " --column=" . column . " " 142 | let command = RCT_command_with_test_options(command) . tmpfile 143 | "let term = matchstr(system(command), "\\v[^\n]+") 144 | exec system(command) 145 | call delete(tmpfile) 146 | "call RCT_find_tag_or_ri(term) 147 | endfunction 148 | 149 | function! RCT_ruby_toggle() 150 | let curr_file = expand("%:p") 151 | let cmd = "ruby -S ruby-toggle-file " . curr_file 152 | if match(curr_file, '\v_test|test_') != -1 153 | let s:last_test_file = curr_file 154 | let s:last_test_lineno = line(".") 155 | endif 156 | let dest = system(cmd) 157 | silent exec ":w" 158 | exec ("edit " . dest) 159 | silent! normal g; 160 | endfunction 161 | 162 | "{{{ bindings and au 163 | 164 | if v:version >= 700 165 | execute "au Filetype ruby setlocal completefunc=" . s:sid . "RCT_completion" 166 | endif 167 | execute 'au Filetype ruby nmap :exec "call ' . 168 | \ 'RCT_find_tag_or_ri(''" . expand("") . "'')"' 169 | execute 'au Filetype ruby nmap ' . s:GetOption("RCT_ri_binding", "r") . 170 | \ ' :call ' . s:sid . 'RCT_smart_ri()' 171 | execute 'au Filetype ruby nmap ' . s:GetOption("RCT_toggle_binding", "t") . 172 | \ ' :call ' . s:sid . 'RCT_ruby_toggle()' 173 | let &cpo = s:save_cpo 174 | -------------------------------------------------------------------------------- /test/attic/test_run.rb: -------------------------------------------------------------------------------- 1 | require 'test/unit' 2 | require 'rcodetools/xmpfilter' 3 | require 'rcodetools/xmptestunitfilter' 4 | require 'rcodetools/completion' 5 | require 'rcodetools/doc' 6 | require 'rcodetools/options' 7 | require 'stringio' 8 | 9 | class TestRun < Test::Unit::TestCase 10 | include Rcodetools 11 | DIR = File.expand_path(File.dirname(__FILE__)) 12 | 13 | tests = { 14 | :simple_annotation => {:klass => XMPFilter}, 15 | :unit_test => {:klass => XMPTestUnitFilter}, 16 | :rspec => {:klass => XMPRSpecFilter, :interpreter => "spec"}, 17 | :rspec_poetry => {:klass => XMPRSpecFilter, :interpreter => "spec", :use_parentheses => false}, 18 | :no_warnings => {:klass => XMPFilter, :warnings => false}, 19 | :bindings => {:klass => XMPTestUnitFilter, :use_parentheses => false}, 20 | :unit_test_poetry => {:klass => XMPTestUnitFilter, :use_parentheses => false}, 21 | :add_markers => {:klass => XMPAddMarkers}, 22 | 23 | :completion => {:klass => XMPCompletionFilter, :lineno => 1}, 24 | :completion_emacs => {:klass => XMPCompletionEmacsFilter, :lineno => 1}, 25 | :completion_emacs_icicles => {:klass => XMPCompletionEmacsIciclesFilter, :lineno => 1}, 26 | :completion_class_info => {:klass => XMPCompletionClassInfoFilter, :lineno => 1}, 27 | :completion_class_info_no_candidates => {:klass => XMPCompletionClassInfoFilter, :lineno => 1}, 28 | 29 | :doc => {:klass => XMPDocFilter, :lineno => 1}, 30 | :refe => {:klass => XMPReFeFilter, :lineno => 1}, 31 | :ri => {:klass => XMPRiFilter, :lineno => 1}, 32 | :ri_emacs => {:klass => XMPRiEmacsFilter, :lineno => 1}, 33 | :ri_vim => {:klass => XMPRiVimFilter, :lineno => 1}, 34 | 35 | } 36 | tests.each_pair do |test, opts| 37 | define_method("test_#{test}") do 38 | inputfile = "#{DIR}/data/#{test}-input.rb" 39 | outputfile = "#{DIR}/data/#{test}-output.rb" 40 | sio = StringIO.new 41 | sio.puts opts[:klass].run(File.read(inputfile), DEFAULT_OPTIONS.merge(opts)) 42 | assert_equal(File.read(outputfile), sio.string) 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /test/data/attic/add_markers-input.rb: -------------------------------------------------------------------------------- 1 | 1+1 2 | 2+3 3 | -------------------------------------------------------------------------------- /test/data/attic/add_markers-output.rb: -------------------------------------------------------------------------------- 1 | 1+1 # => 2 | 2+3 # => 3 | -------------------------------------------------------------------------------- /test/data/attic/bindings-input.rb: -------------------------------------------------------------------------------- 1 | 2 | require 'test/unit' 3 | 4 | class TestFoo < Test::Unit::TestCase 5 | def setup 6 | @o = [] 7 | end 8 | 9 | def test_foo 10 | a = 1 11 | b = a 12 | b # => 13 | end 14 | 15 | def test_arr 16 | last = 1 17 | @o << last 18 | @o.last # => 19 | end 20 | 21 | def test_bar 22 | a = b = c = 1 23 | d = a 24 | d # => 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /test/data/attic/bindings-output.rb: -------------------------------------------------------------------------------- 1 | 2 | require 'test/unit' 3 | 4 | class TestFoo < Test::Unit::TestCase 5 | def setup 6 | @o = [] 7 | end 8 | 9 | def test_foo 10 | a = 1 11 | b = a 12 | assert_equal a, b 13 | assert_equal 1, b 14 | end 15 | 16 | def test_arr 17 | last = 1 18 | @o << last 19 | assert_equal last, @o.last 20 | assert_equal 1, @o.last 21 | end 22 | 23 | def test_bar 24 | a = b = c = 1 25 | d = a 26 | assert_equal a, d 27 | assert_equal b, d 28 | assert_equal c, d 29 | assert_equal 1, d 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /test/data/attic/completion-input.rb: -------------------------------------------------------------------------------- 1 | Array.new(3).uni 2 | -------------------------------------------------------------------------------- /test/data/attic/completion-output.rb: -------------------------------------------------------------------------------- 1 | uniq 2 | uniq! 3 | -------------------------------------------------------------------------------- /test/data/attic/completion_class_info-input.rb: -------------------------------------------------------------------------------- 1 | Array.new(3).s -------------------------------------------------------------------------------- /test/data/attic/completion_class_info-output.rb: -------------------------------------------------------------------------------- 1 | select Array#select 2 | send Object#send 3 | shift Array#shift 4 | singleton_methods Object#singleton_methods 5 | size Array#size 6 | slice Array#slice 7 | slice! Array#slice! 8 | sort Array#sort 9 | sort! Array#sort! 10 | sort_by Enumerable#sort_by 11 | -------------------------------------------------------------------------------- /test/data/attic/completion_class_info_no_candidates-input.rb: -------------------------------------------------------------------------------- 1 | Array.new(3).nonexisten -------------------------------------------------------------------------------- /test/data/attic/completion_class_info_no_candidates-output.rb: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test/data/attic/completion_detect_rbtest-input.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | =begin test_bar 3 | assert_equal "BAR", bar("bar") 4 | =end 5 | def bar(s) 6 | s.upca 7 | end 8 | -------------------------------------------------------------------------------- /test/data/attic/completion_detect_rbtest-output.rb: -------------------------------------------------------------------------------- 1 | upcase 2 | upcase! 3 | -------------------------------------------------------------------------------- /test/data/attic/completion_detect_rbtest2-input.rb: -------------------------------------------------------------------------------- 1 | Array.new(3).uni 2 | -------------------------------------------------------------------------------- /test/data/attic/completion_detect_rbtest2-output.rb: -------------------------------------------------------------------------------- 1 | uniq 2 | uniq! 3 | -------------------------------------------------------------------------------- /test/data/attic/completion_emacs-input.rb: -------------------------------------------------------------------------------- 1 | Array.new(3).uni 2 | -------------------------------------------------------------------------------- /test/data/attic/completion_emacs-output.rb: -------------------------------------------------------------------------------- 1 | (progn 2 | (setq rct-method-completion-table '(("uniq") ("uniq!") )) 3 | (setq alist '(("uniq\t[Array#uniq]") ("uniq!\t[Array#uniq!]") )) 4 | (setq pattern "uni") 5 | (try-completion pattern rct-method-completion-table nil) 6 | ) 7 | -------------------------------------------------------------------------------- /test/data/attic/completion_emacs_icicles-input.rb: -------------------------------------------------------------------------------- 1 | 1.div 2 | -------------------------------------------------------------------------------- /test/data/attic/completion_emacs_icicles-output.rb: -------------------------------------------------------------------------------- 1 | (progn 2 | (setq rct-method-completion-table '(("div\t[Fixnum#div]") ("divmod\t[Fixnum#divmod]") )) 3 | (setq alist '(("div" . "Fixnum#div")("divmod" . "Fixnum#divmod"))) 4 | (setq pattern "div") 5 | (setq klass "Fixnum") 6 | ) 7 | -------------------------------------------------------------------------------- /test/data/attic/completion_in_method-input.rb: -------------------------------------------------------------------------------- 1 | def fooz 2 | [].lengt 3 | end 4 | -------------------------------------------------------------------------------- /test/data/attic/completion_in_method-output.rb: -------------------------------------------------------------------------------- 1 | length 2 | -------------------------------------------------------------------------------- /test/data/attic/completion_in_method-test.rb: -------------------------------------------------------------------------------- 1 | require 'test/unit' 2 | class TestFooz < Test::Unit::TestCase 3 | def test_fooz 4 | assert_equal(0, fooz) 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /test/data/attic/completion_rbtest-input.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | =begin test_bar 3 | assert_equal "BAR", bar("bar") 4 | =end 5 | def bar(s) 6 | s.upca 7 | end 8 | -------------------------------------------------------------------------------- /test/data/attic/completion_rbtest-output.rb: -------------------------------------------------------------------------------- 1 | upcase 2 | upcase! 3 | -------------------------------------------------------------------------------- /test/data/attic/doc-input.rb: -------------------------------------------------------------------------------- 1 | [].length 2 | -------------------------------------------------------------------------------- /test/data/attic/doc-output.rb: -------------------------------------------------------------------------------- 1 | Array#length 2 | -------------------------------------------------------------------------------- /test/data/attic/doc_detect_rbtest-input.rb: -------------------------------------------------------------------------------- 1 | [].length 2 | -------------------------------------------------------------------------------- /test/data/attic/doc_detect_rbtest-output.rb: -------------------------------------------------------------------------------- 1 | Array#length 2 | -------------------------------------------------------------------------------- /test/data/attic/doc_detect_rbtest2-input.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | =begin test_bar 3 | assert_equal "BAR", bar("bar") 4 | =end 5 | def bar(s) 6 | s.upcase 7 | end 8 | -------------------------------------------------------------------------------- /test/data/attic/doc_detect_rbtest2-output.rb: -------------------------------------------------------------------------------- 1 | String#upcase 2 | -------------------------------------------------------------------------------- /test/data/attic/doc_rbtest-input.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | =begin test_bar 3 | assert_equal "BAR", bar("bar") 4 | =end 5 | def bar(s) 6 | s.upcase 7 | end 8 | -------------------------------------------------------------------------------- /test/data/attic/doc_rbtest-output.rb: -------------------------------------------------------------------------------- 1 | String#upcase 2 | -------------------------------------------------------------------------------- /test/data/attic/no_warnings-input.rb: -------------------------------------------------------------------------------- 1 | A = 1 2 | A = 1 3 | p (1) 4 | -------------------------------------------------------------------------------- /test/data/attic/no_warnings-output.rb: -------------------------------------------------------------------------------- 1 | A = 1 2 | A = 1 3 | p (1) 4 | # >> 1 5 | -------------------------------------------------------------------------------- /test/data/attic/refe-input.rb: -------------------------------------------------------------------------------- 1 | [].length 2 | -------------------------------------------------------------------------------- /test/data/attic/refe-output.rb: -------------------------------------------------------------------------------- 1 | refe 'Array#length' 2 | -------------------------------------------------------------------------------- /test/data/attic/ri-input.rb: -------------------------------------------------------------------------------- 1 | [].length 2 | -------------------------------------------------------------------------------- /test/data/attic/ri-output.rb: -------------------------------------------------------------------------------- 1 | ri 'Array#length' 2 | -------------------------------------------------------------------------------- /test/data/attic/ri_emacs-input.rb: -------------------------------------------------------------------------------- 1 | [].length 2 | -------------------------------------------------------------------------------- /test/data/attic/ri_emacs-output.rb: -------------------------------------------------------------------------------- 1 | (rct-find-tag-or-ri "Array#length") 2 | -------------------------------------------------------------------------------- /test/data/attic/ri_vim-input.rb: -------------------------------------------------------------------------------- 1 | [].length 2 | -------------------------------------------------------------------------------- /test/data/attic/ri_vim-output.rb: -------------------------------------------------------------------------------- 1 | call RCT_find_tag_or_ri("Array#length") 2 | -------------------------------------------------------------------------------- /test/data/attic/rspec-input.rb: -------------------------------------------------------------------------------- 1 | 2 | class X 3 | Y = Struct.new(:a) 4 | def foo(b); b ? Y.new(2) : 2 end 5 | def bar; raise "No good" end 6 | def baz; nil end 7 | def fubar(x); x ** 2.0 + 1 end 8 | def babar; [1,2] end 9 | A = 1 10 | A = 1 11 | end 12 | 13 | 14 | describe "xmpfilter's expectation expansion" do 15 | before do 16 | @o = X.new 17 | end 18 | 19 | it "should expand should == expectations" do 20 | @o.foo(true) # => 21 | @o.foo(true).a # => 22 | @o.foo(false) # => 23 | end 24 | 25 | it "should expand should raise_error expectations" do 26 | @o.bar # => 27 | end 28 | 29 | it "should expand should be_nil expectations" do 30 | @o.baz # => 31 | end 32 | 33 | it "should expand correct expectations for complex values" do 34 | @o.babar # => 35 | end 36 | 37 | it "should expand should be_close expectations" do 38 | @o.fubar(10) # => 39 | end 40 | end 41 | 42 | describe "xmpfilter's automagic binding detection" do 43 | it "should expand should == expectations" do 44 | a = b = c = 1 45 | d = a 46 | d # => 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /test/data/attic/rspec-output.rb: -------------------------------------------------------------------------------- 1 | 2 | class X 3 | Y = Struct.new(:a) 4 | def foo(b); b ? Y.new(2) : 2 end 5 | def bar; raise "No good" end 6 | def baz; nil end 7 | def fubar(x); x ** 2.0 + 1 end 8 | def babar; [1,2] end 9 | A = 1 10 | A = 1 # !> already initialized constant A 11 | end 12 | 13 | 14 | describe "xmpfilter's expectation expansion" do 15 | before do 16 | @o = X.new 17 | end 18 | 19 | it "should expand should == expectations" do 20 | (@o.foo(true)).should be_a_kind_of(X::Y) 21 | (@o.foo(true).inspect).should == ("#") 22 | (@o.foo(true).a).should == (2) 23 | (@o.foo(false)).should == (2) 24 | end 25 | 26 | it "should expand should raise_error expectations" do 27 | lambda{@o.bar}.should raise_error(RuntimeError) 28 | end 29 | 30 | it "should expand should be_nil expectations" do 31 | (@o.baz).should be_nil 32 | end 33 | 34 | it "should expand correct expectations for complex values" do 35 | (@o.babar).should == ([1, 2]) 36 | end 37 | 38 | it "should expand should be_close expectations" do 39 | (@o.fubar(10)).should be_close(101.0, 0.0001) 40 | end 41 | end 42 | 43 | describe "xmpfilter's automagic binding detection" do 44 | it "should expand should == expectations" do 45 | a = b = c = 1 46 | d = a 47 | (d).should == (a) 48 | (d).should == (b) 49 | (d).should == (c) 50 | (d).should == (1) 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /test/data/attic/rspec_poetry-input.rb: -------------------------------------------------------------------------------- 1 | 2 | class X 3 | Y = Struct.new(:a) 4 | def foo(b); b ? Y.new(2) : 2 end 5 | def bar; raise "No good" end 6 | def baz; nil end 7 | def fubar(x); x ** 2.0 + 1 end 8 | def babar; [1,2] end 9 | A = 1 10 | A = 1 11 | end 12 | 13 | 14 | describe "xmpfilter's expectation expansion" do 15 | before do 16 | @o = X.new 17 | end 18 | 19 | it "should expand should == expectations" do 20 | @o.foo(true) # => 21 | @o.foo(true).a # => 22 | @o.foo(false) # => 23 | end 24 | 25 | it "should expand should raise_error expectations" do 26 | @o.bar # => 27 | end 28 | 29 | it "should expand should be_nil expectations" do 30 | @o.baz # => 31 | end 32 | 33 | it "should expand correct expectations for complex values" do 34 | @o.babar # => 35 | end 36 | 37 | it "should expand should be_close expectations" do 38 | @o.fubar(10) # => 39 | end 40 | end 41 | 42 | describe "xmpfilter's automagic binding detection" do 43 | it "should expand should == expectations" do 44 | a = b = c = 1 45 | d = a 46 | d # => 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /test/data/attic/rspec_poetry-output.rb: -------------------------------------------------------------------------------- 1 | 2 | class X 3 | Y = Struct.new(:a) 4 | def foo(b); b ? Y.new(2) : 2 end 5 | def bar; raise "No good" end 6 | def baz; nil end 7 | def fubar(x); x ** 2.0 + 1 end 8 | def babar; [1,2] end 9 | A = 1 10 | A = 1 # !> already initialized constant A 11 | end 12 | 13 | 14 | describe "xmpfilter's expectation expansion" do 15 | before do 16 | @o = X.new 17 | end 18 | 19 | it "should expand should == expectations" do 20 | @o.foo(true).should be_a_kind_of(X::Y) 21 | @o.foo(true).inspect.should == "#" 22 | @o.foo(true).a.should == 2 23 | @o.foo(false).should == 2 24 | end 25 | 26 | it "should expand should raise_error expectations" do 27 | lambda{@o.bar}.should raise_error(RuntimeError) 28 | end 29 | 30 | it "should expand should be_nil expectations" do 31 | @o.baz.should be_nil 32 | end 33 | 34 | it "should expand correct expectations for complex values" do 35 | @o.babar.should == [1, 2] 36 | end 37 | 38 | it "should expand should be_close expectations" do 39 | @o.fubar(10).should be_close(101.0, 0.0001) 40 | end 41 | end 42 | 43 | describe "xmpfilter's automagic binding detection" do 44 | it "should expand should == expectations" do 45 | a = b = c = 1 46 | d = a 47 | d.should == a 48 | d.should == b 49 | d.should == c 50 | d.should == 1 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /test/data/attic/simple_annotation-input.rb: -------------------------------------------------------------------------------- 1 | 2 | a = 1 3 | 10.times do |i| 4 | i ** 2 # => 5 | a += i 6 | end 7 | A = 1 8 | A = 1 9 | -------------------------------------------------------------------------------- /test/data/attic/simple_annotation-output.rb: -------------------------------------------------------------------------------- 1 | 2 | a = 1 3 | 10.times do |i| 4 | i ** 2 # => 0, 1, 4, 9, 16, 25, 36, 49, 64, 81 5 | a += i 6 | end 7 | A = 1 8 | A = 1 # !> already initialized constant A 9 | -------------------------------------------------------------------------------- /test/data/attic/unit_test-input.rb: -------------------------------------------------------------------------------- 1 | 2 | class X 3 | Y = Struct.new(:a) 4 | def foo(b); b ? Y.new(2) : 2 end 5 | def bar; raise "No good" end 6 | def baz; nil end 7 | def fubar(x); x ** 2.0 + 1 end 8 | def babar; [1,2] end 9 | A = 1 10 | A = 1 11 | def difftype() [1, "s"] end 12 | end 13 | 14 | 15 | require 'test/unit' 16 | class Test_X < Test::Unit::TestCase 17 | def setup 18 | @o = X.new 19 | end 20 | 21 | def test_foo 22 | @o.foo(true) # => 23 | @o.foo(true).a # => 24 | @o.foo(false) # => 25 | end 26 | 27 | def test_bar 28 | @o.bar # => 29 | end 30 | 31 | def test_baz 32 | @o.baz # => 33 | end 34 | 35 | def test_babar 36 | @o.babar # => 37 | end 38 | 39 | def test_fubar 40 | @o.fubar(10) # => 41 | end 42 | 43 | def test_difftype 44 | for x in @o.difftype 45 | x # => 46 | end 47 | end 48 | 49 | end 50 | 51 | -------------------------------------------------------------------------------- /test/data/attic/unit_test-output.rb: -------------------------------------------------------------------------------- 1 | 2 | class X 3 | Y = Struct.new(:a) 4 | def foo(b); b ? Y.new(2) : 2 end 5 | def bar; raise "No good" end 6 | def baz; nil end 7 | def fubar(x); x ** 2.0 + 1 end 8 | def babar; [1,2] end 9 | A = 1 10 | A = 1 # !> already initialized constant A 11 | def difftype() [1, "s"] end 12 | end 13 | 14 | 15 | require 'test/unit' 16 | class Test_X < Test::Unit::TestCase 17 | def setup 18 | @o = X.new 19 | end 20 | 21 | def test_foo 22 | assert_kind_of(X::Y, @o.foo(true)) 23 | assert_equal("#", @o.foo(true).inspect) 24 | assert_equal(2, @o.foo(true).a) 25 | assert_equal(2, @o.foo(false)) 26 | end 27 | 28 | def test_bar 29 | assert_raise(RuntimeError){@o.bar} 30 | end 31 | 32 | def test_baz 33 | assert_nil(@o.baz) 34 | end 35 | 36 | def test_babar 37 | assert_equal([1, 2], @o.babar) 38 | end 39 | 40 | def test_fubar 41 | assert_in_delta(101.0, @o.fubar(10), 0.0001) 42 | end 43 | 44 | def test_difftype 45 | for x in @o.difftype 46 | #xmpfilter: WARNING!! extra values ignored 47 | assert_equal(1, x) 48 | end 49 | end 50 | 51 | end 52 | 53 | -------------------------------------------------------------------------------- /test/data/attic/unit_test_detect_rbtest-input.rb: -------------------------------------------------------------------------------- 1 | 2 | class X 3 | Y = Struct.new(:a) 4 | def foo(b); b ? Y.new(2) : 2 end 5 | def bar; raise "No good" end 6 | def baz; nil end 7 | def fubar(x); x ** 2.0 + 1 end 8 | def babar; [1,2] end 9 | A = 1 10 | A = 1 11 | def difftype() [1, "s"] end 12 | end 13 | 14 | 15 | require 'test/unit' 16 | class Test_X < Test::Unit::TestCase 17 | def setup 18 | @o = X.new 19 | end 20 | 21 | def test_foo 22 | @o.foo(true) # => 23 | @o.foo(true).a # => 24 | @o.foo(false) # => 25 | end 26 | 27 | def test_bar 28 | @o.bar # => 29 | end 30 | 31 | def test_baz 32 | @o.baz # => 33 | end 34 | 35 | def test_babar 36 | @o.babar # => 37 | end 38 | 39 | def test_fubar 40 | @o.fubar(10) # => 41 | end 42 | 43 | def test_difftype 44 | for x in @o.difftype 45 | x # => 46 | end 47 | end 48 | 49 | end 50 | 51 | -------------------------------------------------------------------------------- /test/data/attic/unit_test_detect_rbtest-output.rb: -------------------------------------------------------------------------------- 1 | 2 | class X 3 | Y = Struct.new(:a) 4 | def foo(b); b ? Y.new(2) : 2 end 5 | def bar; raise "No good" end 6 | def baz; nil end 7 | def fubar(x); x ** 2.0 + 1 end 8 | def babar; [1,2] end 9 | A = 1 10 | A = 1 # !> already initialized constant A 11 | def difftype() [1, "s"] end 12 | end 13 | 14 | 15 | require 'test/unit' 16 | class Test_X < Test::Unit::TestCase 17 | def setup 18 | @o = X.new 19 | end 20 | 21 | def test_foo 22 | assert_kind_of(X::Y, @o.foo(true)) 23 | assert_equal("#", @o.foo(true).inspect) 24 | assert_equal(2, @o.foo(true).a) 25 | assert_equal(2, @o.foo(false)) 26 | end 27 | 28 | def test_bar 29 | assert_raise(RuntimeError){@o.bar} 30 | end 31 | 32 | def test_baz 33 | assert_nil(@o.baz) 34 | end 35 | 36 | def test_babar 37 | assert_equal([1, 2], @o.babar) 38 | end 39 | 40 | def test_fubar 41 | assert_in_delta(101.0, @o.fubar(10), 0.0001) 42 | end 43 | 44 | def test_difftype 45 | for x in @o.difftype 46 | #xmpfilter: WARNING!! extra values ignored 47 | assert_equal(1, x) 48 | end 49 | end 50 | 51 | end 52 | 53 | -------------------------------------------------------------------------------- /test/data/attic/unit_test_detect_rbtest2-input.rb: -------------------------------------------------------------------------------- 1 | =begin test_bar 2 | bar("bar") # => 3 | =end 4 | def bar(s) 5 | s.upcase 6 | end 7 | -------------------------------------------------------------------------------- /test/data/attic/unit_test_detect_rbtest2-output.rb: -------------------------------------------------------------------------------- 1 | =begin test_bar 2 | assert_equal("BAR", bar("bar")) 3 | =end 4 | def bar(s) 5 | s.upcase 6 | end 7 | -------------------------------------------------------------------------------- /test/data/attic/unit_test_poetry-input.rb: -------------------------------------------------------------------------------- 1 | 2 | class X 3 | Y = Struct.new(:a) 4 | def foo(b); b ? Y.new(2) : 2 end 5 | def bar; raise "No good" end 6 | def baz; nil end 7 | def fubar(x); x ** 2.0 + 1 end 8 | def babar; [1,2] end 9 | A = 1 10 | A = 1 11 | def difftype() [1, "s"] end 12 | end 13 | 14 | 15 | require 'test/unit' 16 | class Test_X < Test::Unit::TestCase 17 | def setup 18 | @o = X.new 19 | end 20 | 21 | def test_foo 22 | @o.foo(true) # => 23 | @o.foo(true).a # => 24 | @o.foo(false) # => 25 | end 26 | 27 | def test_bar 28 | @o.bar # => 29 | end 30 | 31 | def test_baz 32 | @o.baz # => 33 | end 34 | 35 | def test_babar 36 | @o.babar # => 37 | end 38 | 39 | def test_fubar 40 | @o.fubar(10) # => 41 | end 42 | 43 | def test_difftype 44 | for x in @o.difftype 45 | x # => 46 | end 47 | end 48 | 49 | end 50 | 51 | -------------------------------------------------------------------------------- /test/data/attic/unit_test_poetry-output.rb: -------------------------------------------------------------------------------- 1 | 2 | class X 3 | Y = Struct.new(:a) 4 | def foo(b); b ? Y.new(2) : 2 end 5 | def bar; raise "No good" end 6 | def baz; nil end 7 | def fubar(x); x ** 2.0 + 1 end 8 | def babar; [1,2] end 9 | A = 1 10 | A = 1 # !> already initialized constant A 11 | def difftype() [1, "s"] end 12 | end 13 | 14 | 15 | require 'test/unit' 16 | class Test_X < Test::Unit::TestCase 17 | def setup 18 | @o = X.new 19 | end 20 | 21 | def test_foo 22 | assert_kind_of X::Y, @o.foo(true) 23 | assert_equal "#", @o.foo(true).inspect 24 | assert_equal 2, @o.foo(true).a 25 | assert_equal 2, @o.foo(false) 26 | end 27 | 28 | def test_bar 29 | assert_raise(RuntimeError){@o.bar} 30 | end 31 | 32 | def test_baz 33 | assert_nil @o.baz 34 | end 35 | 36 | def test_babar 37 | assert_equal [1, 2], @o.babar 38 | end 39 | 40 | def test_fubar 41 | assert_in_delta 101.0, @o.fubar(10), 0.0001 42 | end 43 | 44 | def test_difftype 45 | for x in @o.difftype 46 | #xmpfilter: WARNING!! extra values ignored 47 | assert_equal 1, x 48 | end 49 | end 50 | 51 | end 52 | 53 | -------------------------------------------------------------------------------- /test/data/attic/unit_test_rbtest-input.rb: -------------------------------------------------------------------------------- 1 | =begin test_bar 2 | bar("bar") # => 3 | =end 4 | def bar(s) 5 | s.upcase 6 | end 7 | -------------------------------------------------------------------------------- /test/data/attic/unit_test_rbtest-output.rb: -------------------------------------------------------------------------------- 1 | =begin test_bar 2 | assert_equal("BAR", bar("bar")) 3 | =end 4 | def bar(s) 5 | s.upcase 6 | end 7 | -------------------------------------------------------------------------------- /test/data/method_analyzer-data.rb: -------------------------------------------------------------------------------- 1 | 2 | class A 3 | def A.foo 4 | 1 5 | end 6 | 7 | def a 8 | 1+1 9 | end 10 | end 11 | class B < A 12 | def initialize 13 | end 14 | attr_accessor :bb 15 | 16 | def b 17 | "a".length 18 | end 19 | end 20 | tm = Time.now 21 | [tm.year, tm.month, tm.day] << 0 22 | a = A.new 23 | a.a 24 | b = B.new 25 | b.a 26 | b.b 27 | [b.a,b.b] 28 | z = b.a + b.b 29 | A.foo 30 | B.foo 31 | b.bb=1 32 | b.bb 33 | 34 | -------------------------------------------------------------------------------- /test/data/method_args.data.rb: -------------------------------------------------------------------------------- 1 | # method_args.data.rb 2 | class FixedArgsMethods 3 | def self.singleton(a1) end 4 | def initialize(arg) end 5 | def f(a1) end 6 | def b(a1,&block) end 7 | define_method(:defmethod) {|a1|} 8 | attr_accessor :by_attr_accessor 9 | attr :by_attr_false 10 | attr :by_attr_true, true 11 | attr_reader :by_attr_reader_1, :by_attr_reader_2 12 | attr_writer :by_attr_writer 13 | def private_meth(x) end 14 | private :private_meth 15 | class << self 16 | attr_accessor :singleton_attr_accessor 17 | define_method(:singleton_defmethod){|a2|} 18 | end 19 | end 20 | 21 | module VariableArgsMethods 22 | def s(a1,*splat) end 23 | def sb(a1,*splat, &block) end 24 | def d(a1,default=nil) end 25 | def ds(a1,default=nil,*splat) end 26 | def dsb(a1,default=nil,*splat,&block) end 27 | def db(a1,default=nil,&block) end 28 | end 29 | 30 | class Fixnum 31 | def method_in_Fixnum(arg1, arg2) end 32 | def self.singleton_method_in_Fixnum(arg1, arg2) end 33 | end 34 | class Bignum 35 | def method_in_Bignum(arg1, arg2) end 36 | end 37 | class Float 38 | def method_in_Float(arg1, arg2) end 39 | end 40 | class Symbol 41 | def method_in_Symbol(arg1, arg2) end 42 | end 43 | class Binding 44 | def method_in_Binding(arg1, arg2) end 45 | end 46 | class UnboundMethod 47 | def method_in_UnboundMethod(arg1, arg2) end 48 | end 49 | class Method 50 | def method_in_Method(arg1, arg2) end 51 | end 52 | class Proc 53 | def method_in_Proc(arg1, arg2) end 54 | end 55 | class Continuation 56 | def method_in_Continuation(arg1, arg2) end 57 | end 58 | class Thread 59 | def method_in_Thread(arg1, arg2) end 60 | end 61 | # FIXME mysterious 62 | # class FalseClass 63 | # def method_in_FalseClass(arg1, arg2) end 64 | # end 65 | class TrueClass 66 | def method_in_TrueClass(arg1, arg2) end 67 | end 68 | class NilClass 69 | def method_in_NilClass(arg1, arg2) end 70 | end 71 | class Struct 72 | def method_in_Struct(arg1, arg2) end 73 | end 74 | 75 | require 'digest' 76 | class Digest::Base 77 | def method_in_Digest_Base(arg1, arg2) end 78 | end 79 | 80 | class AnAbstractClass 81 | $__method_args_off = true 82 | def self.allocate 83 | raise NotImplementedError, "#{self} is an abstract class." 84 | end 85 | $__method_args_off = false 86 | 87 | def method_in_AnAbstractClass(arg1, arg2) 88 | end 89 | 90 | end 91 | 92 | class AClass 93 | include VariableArgsMethods 94 | extend VariableArgsMethods 95 | end 96 | 97 | class ASubClass < AClass 98 | end 99 | 100 | StructA = Struct.new :a, :b 101 | class SubclassOfStructA < StructA 102 | attr :method_in_b 103 | end 104 | class StructSubclass < Struct.new(:c) 105 | attr :method_in_c 106 | end 107 | -------------------------------------------------------------------------------- /test/data/rct-complete-TDC/completion_in_method__testmethod.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | completion_in_method__testmethod 3 | ========== 4 | rct-complete --filename %s --line 2 -t %s@test_fooz 5 | ========== 6 | def fooz 7 | [].lengt 8 | end 9 | ========== 10 | length 11 | ========== 12 | require 'test/unit' 13 | class TestFooz < Test::Unit::TestCase 14 | def test_fooz 15 | assert_equal(0, fooz) 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /test/data/rct-complete-TDC/completion_in_method__testscript.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | completion_in_method__testscript 3 | ========== 4 | rct-complete --filename %s --line 2 -t %s 5 | ========== 6 | def fooz 7 | [].lengt 8 | end 9 | ========== 10 | length 11 | ========== 12 | require 'test/unit' 13 | class TestFooz < Test::Unit::TestCase 14 | def test_fooz 15 | assert_equal(0, fooz) 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /test/data/rct-complete-TDC/completion_in_method__wrong_testmethod.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | completion_in_method__wrong_testmethod 3 | ========== 4 | rct-complete --filename %s --line 2 -t %s@test_NOT_FOUND 5 | ========== 6 | def fooz 7 | [].lengt 8 | end 9 | ========== 10 | 11 | ========== 12 | require 'test/unit' 13 | class TestFooz < Test::Unit::TestCase 14 | def test_fooz 15 | assert_equal(0, fooz) 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /test/data/rct-complete/completion.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | completion 3 | ========== 4 | rct-complete -C --line=1 5 | ========== 6 | Array.new(3).uni 7 | ========== 8 | uniq 9 | uniq! 10 | -------------------------------------------------------------------------------- /test/data/rct-complete/completion_class_info.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | completion_class_info 3 | ========== 4 | rct-complete --completion-class-info --line=1 5 | ========== 6 | Array.new(3).sl 7 | ========== 8 | slice Array#slice 9 | slice! Array#slice! 10 | -------------------------------------------------------------------------------- /test/data/rct-complete/completion_class_info_no_candidates.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | completion_class_info_no_candidates 3 | ========== 4 | rct-complete --completion-class-info --line=1 5 | ========== 6 | Array.new(3).nonexisten 7 | ========== 8 | 9 | -------------------------------------------------------------------------------- /test/data/rct-complete/completion_detect_rbtest.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | completion_detect_rbtest 3 | ========== 4 | rct-complete --detect-rbtest --line=6 5 | ========== 6 | #!/usr/bin/env ruby 7 | =begin test_bar 8 | assert_equal "BAR", bar("bar") 9 | =end 10 | def bar(s) 11 | s.upca 12 | end 13 | ========== 14 | upcase 15 | upcase! 16 | -------------------------------------------------------------------------------- /test/data/rct-complete/completion_detect_rbtest2.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | completion_detect_rbtest2 3 | ========== 4 | rct-complete --detect-rbtest --line=1 5 | ========== 6 | Array.new(3).uni 7 | ========== 8 | uniq 9 | uniq! 10 | -------------------------------------------------------------------------------- /test/data/rct-complete/completion_emacs.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | completion_emacs 3 | ========== 4 | rct-complete --completion-emacs --line=1 5 | ========== 6 | Array.new(3).uni 7 | ========== 8 | (progn 9 | (setq rct-method-completion-table '(("uniq") ("uniq!") )) 10 | (setq alist '(("uniq\t[Array#uniq]") ("uniq!\t[Array#uniq!]") )) 11 | (setq pattern "uni") 12 | (try-completion pattern rct-method-completion-table nil) 13 | ) 14 | -------------------------------------------------------------------------------- /test/data/rct-complete/completion_emacs_icicles.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | completion_emacs_icicles 3 | ========== 4 | rct-complete --completion-emacs-icicles --line=1 5 | ========== 6 | 1.div 7 | ========== 8 | (progn 9 | (setq rct-method-completion-table '(("div\t[Fixnum#div]") ("divmod\t[Fixnum#divmod]") )) 10 | (setq alist '(("div" . "Fixnum#div")("divmod" . "Fixnum#divmod"))) 11 | (setq pattern "div") 12 | (setq klass "Fixnum") 13 | ) 14 | -------------------------------------------------------------------------------- /test/data/rct-complete/completion_rbtest.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | completion_rbtest 3 | ========== 4 | rct-complete --rbtest --line=6 5 | ========== 6 | #!/usr/bin/env ruby 7 | =begin test_bar 8 | assert_equal "BAR", bar("bar") 9 | =end 10 | def bar(s) 11 | s.upca 12 | end 13 | ========== 14 | upcase 15 | upcase! 16 | -------------------------------------------------------------------------------- /test/data/rct-doc/doc.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | doc 3 | ========== 4 | rct-doc -D --line=1 5 | ========== 6 | [].length 7 | ========== 8 | Array#length 9 | -------------------------------------------------------------------------------- /test/data/rct-doc/doc_detect_rbtest.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | doc_detect_rbtest 3 | ========== 4 | rct-doc --detect-rbtest --line=1 5 | ========== 6 | [].length 7 | ========== 8 | Array#length 9 | -------------------------------------------------------------------------------- /test/data/rct-doc/doc_detect_rbtest2.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | doc_detect_rbtest2 3 | ========== 4 | rct-doc --detect-rbtest --line=6 5 | ========== 6 | #!/usr/bin/env ruby 7 | =begin test_bar 8 | assert_equal "BAR", bar("bar") 9 | =end 10 | def bar(s) 11 | s.upcase 12 | end 13 | ========== 14 | String#upcase 15 | -------------------------------------------------------------------------------- /test/data/rct-doc/doc_rbtest.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | doc_rbtest 3 | ========== 4 | rct-doc --rbtest --line=6 5 | ========== 6 | #!/usr/bin/env ruby 7 | =begin test_bar 8 | assert_equal "BAR", bar("bar") 9 | =end 10 | def bar(s) 11 | s.upcase 12 | end 13 | ========== 14 | String#upcase 15 | -------------------------------------------------------------------------------- /test/data/rct-doc/refe.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | refe 3 | ========== 4 | rct-doc --refe --line=1 5 | ========== 6 | [].length 7 | ========== 8 | refe 'Array#length' 9 | -------------------------------------------------------------------------------- /test/data/rct-doc/ri.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | ri 3 | ========== 4 | rct-doc --ri --line=1 5 | ========== 6 | [].length 7 | ========== 8 | ri 'Array#length' 9 | -------------------------------------------------------------------------------- /test/data/rct-doc/ri_emacs.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | ri_emacs 3 | ========== 4 | rct-doc --ri-emacs --line=1 5 | ========== 6 | [].length 7 | ========== 8 | (rct-find-tag-or-ri "Array#length") 9 | -------------------------------------------------------------------------------- /test/data/rct-doc/ri_vim.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | ri_vim 3 | ========== 4 | rct-doc --ri-vim --line=1 5 | ========== 6 | [].length 7 | ========== 8 | call RCT_find_tag_or_ri("Array#length") 9 | -------------------------------------------------------------------------------- /test/data/sample_test_script.rb: -------------------------------------------------------------------------------- 1 | require 'test/unit' 2 | class TestSample < Test::Unit::TestCase 3 | def test_sample0 4 | assert(true) 5 | end 6 | 7 | def test_sample1 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /test/data/xmpfilter/add_markers.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | add_markers 3 | ========== 4 | xmpfilter -m 5 | ========== 6 | 1+1 7 | 2+3 8 | ========== 9 | 1+1 # => 10 | 2+3 # => 11 | -------------------------------------------------------------------------------- /test/data/xmpfilter/bindings.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | bindings 3 | ========== 4 | xmpfilter --poetry -u 5 | ========== 6 | 7 | require 'test/unit' 8 | 9 | class TestFoo < Test::Unit::TestCase 10 | def setup 11 | @o = [] 12 | end 13 | 14 | def test_foo 15 | a = 1 16 | b = a 17 | b # => 18 | end 19 | 20 | def test_arr 21 | last = 1 22 | @o << last 23 | @o.last # => 24 | end 25 | 26 | def test_bar 27 | a = b = c = 1 28 | d = a 29 | d # => 30 | end 31 | end 32 | ========== 33 | 34 | require 'test/unit' 35 | 36 | class TestFoo < Test::Unit::TestCase 37 | def setup 38 | @o = [] 39 | end 40 | 41 | def test_foo 42 | a = 1 43 | b = a 44 | assert_equal a, b 45 | assert_equal 1, b 46 | end 47 | 48 | def test_arr 49 | last = 1 50 | @o << last 51 | assert_equal last, @o.last 52 | assert_equal 1, @o.last 53 | end 54 | 55 | def test_bar 56 | a = b = c = 1 57 | d = a 58 | assert_equal a, d 59 | assert_equal b, d 60 | assert_equal c, d 61 | assert_equal 1, d 62 | end 63 | end 64 | -------------------------------------------------------------------------------- /test/data/xmpfilter/comment_out.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | comment_out 3 | ========== 4 | xmpfilter 5 | ========== 6 | 7 | # 1 # => 8 | # 1 # => 2 9 | 1 # => 12 10 | 1 11 | # # => 12 | # 1 13 | # # => 14 | ========== 15 | 16 | # 1 # => 17 | # 1 # => 2 18 | 1 # => 1 19 | 1 20 | # # => 21 | # 1 22 | # # => 23 | -------------------------------------------------------------------------------- /test/data/xmpfilter/exception.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | exception 3 | ========== 4 | xmpfilter 5 | ========== 6 | def foo 7 | raise NameError, "ERR!!" rescue $@ # => 8 | end 9 | foo 10 | ========== 11 | def foo 12 | raise NameError, "ERR!!" rescue $@ # => ["-:2:in `foo'", "-:4"] 13 | end 14 | foo 15 | -------------------------------------------------------------------------------- /test/data/xmpfilter/expectations.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | expectations 3 | ========== 4 | xmpfilter --expectations 5 | ========== 6 | 7 | require 'rubygems' 8 | require 'expectations' 9 | 10 | S = Struct.new :a 11 | Expectations do 12 | 1 + 1 # => 13 | "a".length # => 14 | [][1] # => 15 | 1.hoge # => 16 | 1.1 + 1.0 # => 17 | S.new(1) # => 18 | end 19 | ========== 20 | 21 | require 'rubygems' 22 | require 'expectations' 23 | 24 | S = Struct.new :a 25 | Expectations do 26 | expect 2 do 27 | 1 + 1 28 | end 29 | 30 | expect 1 do 31 | "a".length 32 | end 33 | 34 | expect nil do 35 | [][1] 36 | end 37 | 38 | expect NoMethodError do 39 | 1.hoge 40 | end 41 | 42 | expect 2.0999..2.1001 do 43 | 1.1 + 1.0 44 | end 45 | 46 | expect S do 47 | S.new(1) 48 | end 49 | 50 | expect "#" do 51 | S.new(1).inspect 52 | end 53 | 54 | end 55 | -------------------------------------------------------------------------------- /test/data/xmpfilter/last_match.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | last_match 3 | ========== 4 | xmpfilter 5 | ========== 6 | 7 | md = "abc".match(/(.)(.)./) 8 | 1 9 | # => 10 | [$1, $2] # => 11 | $1 # => 12 | ========== 13 | 14 | md = "abc".match(/(.)(.)./) 15 | 1 16 | # => 1 17 | [$1, $2] # => ["a", "b"] 18 | $1 # => "a" 19 | -------------------------------------------------------------------------------- /test/data/xmpfilter/mult.rb: -------------------------------------------------------------------------------- 1 | a = ["1111111111111111111111111111111111111111111111111111", 123334324234242342, 2 | 1332333333,6,8 ] 3 | 1 # => 1 4 | a 5 | # => ["1111111111111111111111111111111111111111111111111111", 6 | # 123334324234242342, 7 | # 1332333333, 8 | # 6, 9 | # 8] 10 | -------------------------------------------------------------------------------- /test/data/xmpfilter/multi_line_annotation_1.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | multi_line_annotation_1 3 | ========== 4 | xmpfilter 5 | ========== 6 | 7 | 1+2 # => 8 | a = ["1111111111111111111111111111111111111111111111111111", 123334324234242342, 9 | 1332333333 ] 10 | 1+2 # => 11 | a 12 | # => 13 | ========== 14 | 15 | 1+2 # => 3 16 | a = ["1111111111111111111111111111111111111111111111111111", 123334324234242342, 17 | 1332333333 ] 18 | 1+2 # => 3 19 | a 20 | # => ["1111111111111111111111111111111111111111111111111111", 21 | # 123334324234242342, 22 | # 1332333333] 23 | -------------------------------------------------------------------------------- /test/data/xmpfilter/multi_line_annotation_2.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | multi_line_annotation_2 3 | ========== 4 | xmpfilter 5 | ========== 6 | 7 | 1+2 # => 32 8 | a = ["1111111111111111111111111111111111111111111111111111", 123334324234242342, 9 | 55555555 ] 10 | 1+2 # => 300 11 | a 12 | # => ["1111111111111111111111111111111111111111111111111111", 13 | # 123334324234242342, 14 | # 1332333333] 15 | ========== 16 | 17 | 1+2 # => 3 18 | a = ["1111111111111111111111111111111111111111111111111111", 123334324234242342, 19 | 55555555 ] 20 | 1+2 # => 3 21 | a 22 | # => ["1111111111111111111111111111111111111111111111111111", 23 | # 123334324234242342, 24 | # 55555555] 25 | -------------------------------------------------------------------------------- /test/data/xmpfilter/multi_line_annotation_3.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | multi_line_annotation_3 3 | ========== 4 | xmpfilter 5 | ========== 6 | 7 | a = ["1111111111111111111111111111111111111111111111111111", 123334324234242342, 8 | 1332333333 ] 9 | a 10 | # => 11 | 1 # => 12 | ========== 13 | 14 | a = ["1111111111111111111111111111111111111111111111111111", 123334324234242342, 15 | 1332333333 ] 16 | a 17 | # => ["1111111111111111111111111111111111111111111111111111", 18 | # 123334324234242342, 19 | # 1332333333] 20 | 1 # => 1 21 | -------------------------------------------------------------------------------- /test/data/xmpfilter/multi_line_annotation_4.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | multi_line_annotation_4 3 | ========== 4 | xmpfilter 5 | ========== 6 | 7 | a = ["1111111111111111111111111111111111111111111111111111", 123334324234242342, 8 | 55555555 ] 9 | a 10 | # => ["1111111111111111111111111111111111111111111111111111", 11 | # 123334324234242342, 12 | # 1332333333] 13 | # not removed 14 | ========== 15 | 16 | a = ["1111111111111111111111111111111111111111111111111111", 123334324234242342, 17 | 55555555 ] 18 | a 19 | # => ["1111111111111111111111111111111111111111111111111111", 20 | # 123334324234242342, 21 | # 55555555] 22 | # not removed 23 | -------------------------------------------------------------------------------- /test/data/xmpfilter/multi_line_annotation_5.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | multi_line_annotation_5 3 | ========== 4 | xmpfilter 5 | ========== 6 | 7 | def test 8 | a = ["1111111111111111111111111111111111111111111111111111", 123334324234242342, 9 | 55555555 ] 10 | a 11 | # => ["", 12 | # 123334324234242342, 13 | # 1332333333] 14 | a 15 | # => 16 | # not removed 17 | end 18 | test 19 | ========== 20 | 21 | def test 22 | a = ["1111111111111111111111111111111111111111111111111111", 123334324234242342, 23 | 55555555 ] 24 | a 25 | # => ["1111111111111111111111111111111111111111111111111111", 26 | # 123334324234242342, 27 | # 55555555] 28 | a 29 | # => ["1111111111111111111111111111111111111111111111111111", 30 | # 123334324234242342, 31 | # 55555555] 32 | # not removed 33 | end 34 | test 35 | -------------------------------------------------------------------------------- /test/data/xmpfilter/multi_line_annotation_6.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | multi_line_annotation_6 3 | ========== 4 | xmpfilter 5 | ========== 6 | 7 | 1 + 2 # !> warning 8 | # => 9 | ========== 10 | 11 | 1 + 2 12 | # => 3 13 | -------------------------------------------------------------------------------- /test/data/xmpfilter/multi_line_annotation_7.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | multi_line_annotation_7 3 | ========== 4 | xmpfilter 5 | ========== 6 | 7 | [1,2] 8 | # => 9 | raise 10 | [3,4] 11 | # => 12 | [5,6] 13 | # => 14 | ========== 15 | 16 | [1,2] 17 | # => [1, 2] 18 | raise 19 | [3,4] 20 | # => 21 | [5,6] 22 | # => 23 | # ~> -:2: unhandled exception 24 | -------------------------------------------------------------------------------- /test/data/xmpfilter/no_warnings.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | no_warnings 3 | ========== 4 | xmpfilter --no-warnings 5 | ========== 6 | A = 1 7 | A = 1 8 | p (1) 9 | ========== 10 | A = 1 11 | A = 1 12 | p (1) 13 | # >> 1 14 | -------------------------------------------------------------------------------- /test/data/xmpfilter/nospace.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | nospace_annotation 3 | ========== 4 | xmpfilter 5 | ========== 6 | 7 | 1 #=> 8 | 2 #=> 2 9 | 3 10 | #=> 11 | ========== 12 | 13 | 1 # => 1 14 | 2 # => 2 15 | 3 16 | # => 3 17 | -------------------------------------------------------------------------------- /test/data/xmpfilter/rspec.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | rspec 3 | ========== 4 | xmpfilter -s 5 | ========== 6 | 7 | class X 8 | Y = Struct.new(:a) 9 | def foo(b); b ? Y.new(2) : 2 end 10 | def bar; raise "No good" end 11 | def baz; nil end 12 | def fubar(x); x ** 2.0 + 1 end 13 | def babar; [1,2] end 14 | A = 1 15 | A = 1 16 | end 17 | 18 | 19 | describe "xmpfilter's expectation expansion" do 20 | before do 21 | @o = X.new 22 | end 23 | 24 | it "should expand should == expectations" do 25 | @o.foo(true) # => 26 | @o.foo(true).a # => 27 | @o.foo(false) # => 28 | end 29 | 30 | it "should expand should raise_error expectations" do 31 | @o.bar # => 32 | end 33 | 34 | it "should expand should be_nil expectations" do 35 | @o.baz # => 36 | end 37 | 38 | it "should expand correct expectations for complex values" do 39 | @o.babar # => 40 | end 41 | 42 | it "should expand should be_close expectations" do 43 | @o.fubar(10) # => 44 | end 45 | end 46 | 47 | describe "xmpfilter's automagic binding detection" do 48 | it "should expand should == expectations" do 49 | a = b = c = 1 50 | d = a 51 | d # => 52 | end 53 | end 54 | ========== 55 | 56 | class X 57 | Y = Struct.new(:a) 58 | def foo(b); b ? Y.new(2) : 2 end 59 | def bar; raise "No good" end 60 | def baz; nil end 61 | def fubar(x); x ** 2.0 + 1 end 62 | def babar; [1,2] end 63 | A = 1 64 | A = 1 # !> already initialized constant A 65 | end 66 | 67 | 68 | describe "xmpfilter's expectation expansion" do 69 | before do 70 | @o = X.new 71 | end 72 | 73 | it "should expand should == expectations" do 74 | (@o.foo(true)).should be_a_kind_of(X::Y) 75 | (@o.foo(true).inspect).should == ("#") 76 | (@o.foo(true).a).should == (2) 77 | (@o.foo(false)).should == (2) 78 | end 79 | 80 | it "should expand should raise_error expectations" do 81 | lambda{@o.bar}.should raise_error(RuntimeError) 82 | end 83 | 84 | it "should expand should be_nil expectations" do 85 | (@o.baz).should be_nil 86 | end 87 | 88 | it "should expand correct expectations for complex values" do 89 | (@o.babar).should == ([1, 2]) 90 | end 91 | 92 | it "should expand should be_close expectations" do 93 | (@o.fubar(10)).should be_close(101.0, 0.0001) 94 | end 95 | end 96 | 97 | describe "xmpfilter's automagic binding detection" do 98 | it "should expand should == expectations" do 99 | a = b = c = 1 100 | d = a 101 | (d).should == (a) 102 | (d).should == (b) 103 | (d).should == (c) 104 | (d).should == (1) 105 | end 106 | end 107 | -------------------------------------------------------------------------------- /test/data/xmpfilter/rspec_poetry.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | rspec_poetry 3 | ========== 4 | xmpfilter -s --poetry 5 | ========== 6 | 7 | class X 8 | Y = Struct.new(:a) 9 | def foo(b); b ? Y.new(2) : 2 end 10 | def bar; raise "No good" end 11 | def baz; nil end 12 | def fubar(x); x ** 2.0 + 1 end 13 | def babar; [1,2] end 14 | A = 1 15 | A = 1 16 | end 17 | 18 | 19 | describe "xmpfilter's expectation expansion" do 20 | before do 21 | @o = X.new 22 | end 23 | 24 | it "should expand should == expectations" do 25 | @o.foo(true) # => 26 | @o.foo(true).a # => 27 | @o.foo(false) # => 28 | end 29 | 30 | it "should expand should raise_error expectations" do 31 | @o.bar # => 32 | end 33 | 34 | it "should expand should be_nil expectations" do 35 | @o.baz # => 36 | end 37 | 38 | it "should expand correct expectations for complex values" do 39 | @o.babar # => 40 | end 41 | 42 | it "should expand should be_close expectations" do 43 | @o.fubar(10) # => 44 | end 45 | end 46 | 47 | describe "xmpfilter's automagic binding detection" do 48 | it "should expand should == expectations" do 49 | a = b = c = 1 50 | d = a 51 | d # => 52 | end 53 | end 54 | ========== 55 | 56 | class X 57 | Y = Struct.new(:a) 58 | def foo(b); b ? Y.new(2) : 2 end 59 | def bar; raise "No good" end 60 | def baz; nil end 61 | def fubar(x); x ** 2.0 + 1 end 62 | def babar; [1,2] end 63 | A = 1 64 | A = 1 # !> already initialized constant A 65 | end 66 | 67 | 68 | describe "xmpfilter's expectation expansion" do 69 | before do 70 | @o = X.new 71 | end 72 | 73 | it "should expand should == expectations" do 74 | @o.foo(true).should be_a_kind_of(X::Y) 75 | @o.foo(true).inspect.should == "#" 76 | @o.foo(true).a.should == 2 77 | @o.foo(false).should == 2 78 | end 79 | 80 | it "should expand should raise_error expectations" do 81 | lambda{@o.bar}.should raise_error(RuntimeError) 82 | end 83 | 84 | it "should expand should be_nil expectations" do 85 | @o.baz.should be_nil 86 | end 87 | 88 | it "should expand correct expectations for complex values" do 89 | @o.babar.should == [1, 2] 90 | end 91 | 92 | it "should expand should be_close expectations" do 93 | @o.fubar(10).should be_close(101.0, 0.0001) 94 | end 95 | end 96 | 97 | describe "xmpfilter's automagic binding detection" do 98 | it "should expand should == expectations" do 99 | a = b = c = 1 100 | d = a 101 | d.should == a 102 | d.should == b 103 | d.should == c 104 | d.should == 1 105 | end 106 | end 107 | -------------------------------------------------------------------------------- /test/data/xmpfilter/simple_annotation.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | simple_annotation 3 | ========== 4 | xmpfilter 5 | ========== 6 | 7 | a = 1 8 | 10.times do |i| 9 | i ** 2 # => 10 | a += i 11 | end 12 | A = 1 13 | A = 1 14 | ========== 15 | 16 | a = 1 17 | 10.times do |i| 18 | i ** 2 # => 0, 1, 4, 9, 16, 25, 36, 49, 64, 81 19 | a += i 20 | end 21 | A = 1 22 | A = 1 # !> already initialized constant A 23 | -------------------------------------------------------------------------------- /test/data/xmpfilter/unit_test.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | unit_test 3 | ========== 4 | xmpfilter -u 5 | ========== 6 | 7 | class X 8 | Y = Struct.new(:a) 9 | def foo(b); b ? Y.new(2) : 2 end 10 | def bar; raise "No good" end 11 | def baz; nil end 12 | def fubar(x); x ** 2.0 + 1 end 13 | def babar; [1,2] end 14 | A = 1 15 | A = 1 16 | def difftype() [1, "s"] end 17 | end 18 | 19 | 20 | require 'test/unit' 21 | class Test_X < Test::Unit::TestCase 22 | def setup 23 | @o = X.new 24 | end 25 | 26 | def test_foo 27 | @o.foo(true) # => 28 | @o.foo(true).a # => 29 | @o.foo(false) # => 30 | end 31 | 32 | def test_bar 33 | @o.bar # => 34 | end 35 | 36 | def test_baz 37 | @o.baz # => 38 | end 39 | 40 | def test_babar 41 | @o.babar # => 42 | end 43 | 44 | def test_fubar 45 | @o.fubar(10) # => 46 | end 47 | 48 | def test_difftype 49 | for x in @o.difftype 50 | x # => 51 | end 52 | end 53 | 54 | end 55 | 56 | ========== 57 | 58 | class X 59 | Y = Struct.new(:a) 60 | def foo(b); b ? Y.new(2) : 2 end 61 | def bar; raise "No good" end 62 | def baz; nil end 63 | def fubar(x); x ** 2.0 + 1 end 64 | def babar; [1,2] end 65 | A = 1 66 | A = 1 # !> already initialized constant A 67 | def difftype() [1, "s"] end 68 | end 69 | 70 | 71 | require 'test/unit' 72 | class Test_X < Test::Unit::TestCase 73 | def setup 74 | @o = X.new 75 | end 76 | 77 | def test_foo 78 | assert_kind_of(X::Y, @o.foo(true)) 79 | assert_equal("#", @o.foo(true).inspect) 80 | assert_equal(2, @o.foo(true).a) 81 | assert_equal(2, @o.foo(false)) 82 | end 83 | 84 | def test_bar 85 | assert_raise(RuntimeError){@o.bar} 86 | end 87 | 88 | def test_baz 89 | assert_nil(@o.baz) 90 | end 91 | 92 | def test_babar 93 | assert_equal([1, 2], @o.babar) 94 | end 95 | 96 | def test_fubar 97 | assert_in_delta(101.0, @o.fubar(10), 0.0001) 98 | end 99 | 100 | def test_difftype 101 | for x in @o.difftype 102 | #xmpfilter: WARNING!! extra values ignored 103 | assert_equal(1, x) 104 | end 105 | end 106 | 107 | end 108 | 109 | -------------------------------------------------------------------------------- /test/data/xmpfilter/unit_test_detect_rbtest.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | unit_test_detect_rbtest 3 | ========== 4 | xmpfilter -u --detect-rbtest 5 | ========== 6 | 7 | class X 8 | Y = Struct.new(:a) 9 | def foo(b); b ? Y.new(2) : 2 end 10 | def bar; raise "No good" end 11 | def baz; nil end 12 | def fubar(x); x ** 2.0 + 1 end 13 | def babar; [1,2] end 14 | A = 1 15 | A = 1 16 | def difftype() [1, "s"] end 17 | end 18 | 19 | 20 | require 'test/unit' 21 | class Test_X < Test::Unit::TestCase 22 | def setup 23 | @o = X.new 24 | end 25 | 26 | def test_foo 27 | @o.foo(true) # => 28 | @o.foo(true).a # => 29 | @o.foo(false) # => 30 | end 31 | 32 | def test_bar 33 | @o.bar # => 34 | end 35 | 36 | def test_baz 37 | @o.baz # => 38 | end 39 | 40 | def test_babar 41 | @o.babar # => 42 | end 43 | 44 | def test_fubar 45 | @o.fubar(10) # => 46 | end 47 | 48 | def test_difftype 49 | for x in @o.difftype 50 | x # => 51 | end 52 | end 53 | 54 | end 55 | 56 | ========== 57 | 58 | class X 59 | Y = Struct.new(:a) 60 | def foo(b); b ? Y.new(2) : 2 end 61 | def bar; raise "No good" end 62 | def baz; nil end 63 | def fubar(x); x ** 2.0 + 1 end 64 | def babar; [1,2] end 65 | A = 1 66 | A = 1 # !> already initialized constant A 67 | def difftype() [1, "s"] end 68 | end 69 | 70 | 71 | require 'test/unit' 72 | class Test_X < Test::Unit::TestCase 73 | def setup 74 | @o = X.new 75 | end 76 | 77 | def test_foo 78 | assert_kind_of(X::Y, @o.foo(true)) 79 | assert_equal("#", @o.foo(true).inspect) 80 | assert_equal(2, @o.foo(true).a) 81 | assert_equal(2, @o.foo(false)) 82 | end 83 | 84 | def test_bar 85 | assert_raise(RuntimeError){@o.bar} 86 | end 87 | 88 | def test_baz 89 | assert_nil(@o.baz) 90 | end 91 | 92 | def test_babar 93 | assert_equal([1, 2], @o.babar) 94 | end 95 | 96 | def test_fubar 97 | assert_in_delta(101.0, @o.fubar(10), 0.0001) 98 | end 99 | 100 | def test_difftype 101 | for x in @o.difftype 102 | #xmpfilter: WARNING!! extra values ignored 103 | assert_equal(1, x) 104 | end 105 | end 106 | 107 | end 108 | 109 | -------------------------------------------------------------------------------- /test/data/xmpfilter/unit_test_detect_rbtest2.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | unit_test_detect_rbtest2 3 | ========== 4 | xmpfilter --detect-rbtest 5 | ========== 6 | =begin test_bar 7 | bar("bar") # => 8 | =end 9 | def bar(s) 10 | s.upcase 11 | end 12 | ========== 13 | =begin test_bar 14 | assert_equal("BAR", bar("bar")) 15 | =end 16 | def bar(s) 17 | s.upcase 18 | end 19 | -------------------------------------------------------------------------------- /test/data/xmpfilter/unit_test_poetry.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | unit_test_poetry 3 | ========== 4 | xmpfilter -u --poetry 5 | ========== 6 | 7 | class X 8 | Y = Struct.new(:a) 9 | def foo(b); b ? Y.new(2) : 2 end 10 | def bar; raise "No good" end 11 | def baz; nil end 12 | def fubar(x); x ** 2.0 + 1 end 13 | def babar; [1,2] end 14 | A = 1 15 | A = 1 16 | def difftype() [1, "s"] end 17 | end 18 | 19 | 20 | require 'test/unit' 21 | class Test_X < Test::Unit::TestCase 22 | def setup 23 | @o = X.new 24 | end 25 | 26 | def test_foo 27 | @o.foo(true) # => 28 | @o.foo(true).a # => 29 | @o.foo(false) # => 30 | end 31 | 32 | def test_bar 33 | @o.bar # => 34 | end 35 | 36 | def test_baz 37 | @o.baz # => 38 | end 39 | 40 | def test_babar 41 | @o.babar # => 42 | end 43 | 44 | def test_fubar 45 | @o.fubar(10) # => 46 | end 47 | 48 | def test_difftype 49 | for x in @o.difftype 50 | x # => 51 | end 52 | end 53 | 54 | end 55 | 56 | ========== 57 | 58 | class X 59 | Y = Struct.new(:a) 60 | def foo(b); b ? Y.new(2) : 2 end 61 | def bar; raise "No good" end 62 | def baz; nil end 63 | def fubar(x); x ** 2.0 + 1 end 64 | def babar; [1,2] end 65 | A = 1 66 | A = 1 # !> already initialized constant A 67 | def difftype() [1, "s"] end 68 | end 69 | 70 | 71 | require 'test/unit' 72 | class Test_X < Test::Unit::TestCase 73 | def setup 74 | @o = X.new 75 | end 76 | 77 | def test_foo 78 | assert_kind_of X::Y, @o.foo(true) 79 | assert_equal "#", @o.foo(true).inspect 80 | assert_equal 2, @o.foo(true).a 81 | assert_equal 2, @o.foo(false) 82 | end 83 | 84 | def test_bar 85 | assert_raise(RuntimeError){@o.bar} 86 | end 87 | 88 | def test_baz 89 | assert_nil @o.baz 90 | end 91 | 92 | def test_babar 93 | assert_equal [1, 2], @o.babar 94 | end 95 | 96 | def test_fubar 97 | assert_in_delta 101.0, @o.fubar(10), 0.0001 98 | end 99 | 100 | def test_difftype 101 | for x in @o.difftype 102 | #xmpfilter: WARNING!! extra values ignored 103 | assert_equal 1, x 104 | end 105 | end 106 | 107 | end 108 | 109 | -------------------------------------------------------------------------------- /test/data/xmpfilter/unit_test_rbtest.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | unit_test_rbtest 3 | ========== 4 | xmpfilter -u --rbtest 5 | ========== 6 | =begin test_bar 7 | bar("bar") # => 8 | =end 9 | def bar(s) 10 | s.upcase 11 | end 12 | ========== 13 | =begin test_bar 14 | assert_equal("BAR", bar("bar")) 15 | =end 16 | def bar(s) 17 | s.upcase 18 | end 19 | -------------------------------------------------------------------------------- /test/data/xmpfilter/width.taf: -------------------------------------------------------------------------------- 1 | ========== 2 | width 3 | ========== 4 | xmpfilter -w 15 5 | ========== 6 | 7 | a = ["abcdefg", 12345, Object] 8 | a 9 | # => 10 | ========== 11 | 12 | a = ["abcdefg", 12345, Object] 13 | a 14 | # => ["abcdefg", 15 | # 12345, 16 | # Object] 17 | -------------------------------------------------------------------------------- /test/test_functional.rb: -------------------------------------------------------------------------------- 1 | require 'test/unit' 2 | require 'tempfile' 3 | class TestFunctional < Test::Unit::TestCase 4 | def self.parse_taf(filename) 5 | open(filename) do |io| 6 | delimiter=Regexp.union(io.gets) 7 | io.read.split(delimiter) 8 | end 9 | end 10 | 11 | def tempfile_with_contents(contents) 12 | input = Tempfile.new("rct-test") 13 | input.write(contents) 14 | input.close 15 | input.path 16 | end 17 | 18 | DIR = File.expand_path(File.dirname(__FILE__)) 19 | LIBDIR = File.expand_path(DIR + '/../lib') 20 | BINDIR = File.expand_path(DIR + '/../bin') 21 | 22 | # rct-complete-TDC 23 | %w[xmpfilter rct-complete rct-doc].each do |subdir| 24 | Dir["#{DIR}/data/#{subdir}/*.taf"].each do |taf| 25 | desc, cmdline, input, output = parse_taf(taf) 26 | [desc, cmdline].each{|x| x.chomp! } 27 | define_method("test_#{desc}") do 28 | inputfile = tempfile_with_contents(input) 29 | actual_output = `ruby -I#{LIBDIR} #{BINDIR}/#{cmdline} #{inputfile}` 30 | assert_equal output, actual_output 31 | end 32 | end 33 | end 34 | 35 | # TODO 36 | Dir["#{DIR}/data/rct-complete-TDC/*.taf"].each do |taf| 37 | desc, cmdline, input, output, test = parse_taf(taf) 38 | [desc, cmdline].each{|x| x.chomp! } 39 | define_method("test_#{desc}") do 40 | inputfile = tempfile_with_contents(input) 41 | testfile = tempfile_with_contents(test) 42 | actual_output = `ruby -I#{LIBDIR} #{BINDIR}/#{cmdline % [inputfile, testfile]} #{inputfile}` 43 | assert_equal output, actual_output 44 | end 45 | end 46 | 47 | end 48 | -------------------------------------------------------------------------------- /test/test_method_analyzer.rb: -------------------------------------------------------------------------------- 1 | require 'test/unit' 2 | 3 | module ScriptConfig 4 | DIR = File.join(File.expand_path(File.dirname(__FILE__))) 5 | SCRIPT = File.join(DIR, "..", "lib", "method_analyzer.rb") 6 | DATAFILE = File.join(DIR, "data", "method_analyzer-data.rb") 7 | end 8 | 9 | class MethodAnalyzerTextOutput < Test::Unit::TestCase 10 | include ScriptConfig 11 | 12 | # test (find-sh "ruby -r../method_analyzer data/method_analyzer-data.rb") 13 | 14 | # attr_accessor is actually Module#attr_accessor. 15 | # But `f?ri Module.attr_accessor' answers correctly. 16 | expected = < < Struct 59 | method_args.data.rb:101:class SubclassOfStructA < StructA 60 | method_args.data.rb:102:SubclassOfStructA#method_in_b 61 | method_args.data.rb:104:class < Struct 62 | method_args.data.rb:104:class StructSubclass < 63 | method_args.data.rb:105:StructSubclass#method_in_c 64 | XXX 65 | 66 | # To avoid dependency of pwd. 67 | module StripDir 68 | def strip_dir! 69 | slice! %r!^.*/! 70 | self 71 | end 72 | end 73 | 74 | @@expected.each do |line| 75 | begin 76 | file_lineno_klass_meth, rest = line.split(/\s+/,2) 77 | if file_lineno_klass_meth =~ /:/ 78 | file, lineno, klass_meth = file_lineno_klass_meth.split(/:/) 79 | klass_meth = rest if %w[class include extend].include? klass_meth 80 | else # filename/lineno is unknown 81 | klass_meth = file_lineno_klass_meth 82 | end 83 | 84 | test_method_name = "test_" + klass_meth 85 | define_method(test_method_name) do 86 | actual = @@result.grep(/#{klass_meth}/)[0].extend(StripDir).strip_dir! 87 | assert_equal line, actual 88 | end 89 | rescue Exception 90 | end 91 | end 92 | 93 | def test_all_tests 94 | assert_equal @@expected.length, @@result.length, @@result.join("\n") 95 | end 96 | 97 | def test_without_n_option 98 | first_line = "FixedArgsMethods.singleton (a1)" 99 | command_output = `ruby '#{SCRIPT}' '#{DATAFILE}'` 100 | assert_match(/\A#{Regexp.quote(first_line)}\n/, command_output) 101 | end 102 | end 103 | 104 | 105 | class TestTAGS < Test::Unit::TestCase 106 | include MethodArgsScriptConfig 107 | 108 | @@TAGS = `ruby '#{SCRIPT}' -t '#{DATAFILE}'` 109 | def test_filename 110 | # check whether full path is passed. 111 | assert_match %r!^\cl\n/.+method_args.data.rb,\d!, @@TAGS 112 | end 113 | 114 | def test_singleton_method 115 | # including line/byte test 116 | assert @@TAGS.include?(" def self.singleton(a1) end::FixedArgsMethods.singleton3,45") 117 | end 118 | 119 | def test_instance_method 120 | assert @@TAGS.include?(" def initialize(arg) end::FixedArgsMethods#initialize4,74") 121 | end 122 | 123 | def test_include 124 | assert_match(/^ include VariableArgsMethods::AClass/, @@TAGS) 125 | end 126 | 127 | def test_extend 128 | assert_match(/^ extend VariableArgsMethods::AClass/, @@TAGS) 129 | end 130 | 131 | def test_inheritance 132 | assert_match(/^class ASubClass < AClass::ASubClass/, @@TAGS) 133 | end 134 | end 135 | -------------------------------------------------------------------------------- /test/test_options.rb: -------------------------------------------------------------------------------- 1 | $: << ".." << "../lib" 2 | require 'rcodetools/options' 3 | require 'test/unit' 4 | require 'tmpdir' 5 | require 'fileutils' 6 | 7 | class TestOptionHandler < Test::Unit::TestCase 8 | include Rcodetools 9 | include OptionHandler 10 | 11 | def include_paths_check 12 | options = { :include_paths => [] } 13 | auto_include_paths options[:include_paths], Dir.pwd 14 | assert options[:include_paths].include?("#{@basedir}/lib") 15 | assert options[:include_paths].include?("#{@basedir}/bin") 16 | end 17 | 18 | def test_auto_include_paths 19 | Dir.chdir(Dir.tmpdir) do 20 | begin 21 | FileUtils.mkdir_p ["project", "project/lib/project", "project/bin", "project/share"] 22 | open("project/Rakefile","w"){} 23 | @basedir = File.expand_path "project" 24 | Dir.chdir("project/lib/project/") { include_paths_check } 25 | Dir.chdir("project/lib/") { include_paths_check } 26 | Dir.chdir("project/bin/") { include_paths_check } 27 | Dir.chdir("project/") { include_paths_check } 28 | ensure 29 | FileUtils.rm_rf "project" 30 | end 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /test/test_ruby_toggle_file.rb: -------------------------------------------------------------------------------- 1 | require 'fileutils' 2 | require 'test/unit' 3 | require 'ruby_toggle_file' 4 | require 'tmpdir' 5 | 6 | class TestRubyToggleFile < Test::Unit::TestCase 7 | WORK_DIR = "#{Dir.tmpdir}/zdsfwfwejiotest".freeze 8 | FileUtils.rm_rf WORK_DIR 9 | 10 | def teardown 11 | FileUtils.rm_rf WORK_DIR 12 | end 13 | 14 | def create(*files) 15 | for file in files.map{|f| _(f) } 16 | FileUtils.mkpath(File.dirname(file)) 17 | open(file,"w"){} 18 | end 19 | end 20 | 21 | def _(path) # make full path 22 | WORK_DIR + "/" + path 23 | end 24 | 25 | ########################################################################### 26 | # naming convention # 27 | # test_METHOD__EXISTP__IMPLEMENTDIR_TESTDIR # 28 | ########################################################################### 29 | def test_test_file__exist__lib_test 30 | create "lib/zero.rb", "test/test_zero.rb" 31 | rtf = RubyToggleFile.new 32 | assert_equal _("test/test_zero.rb"), rtf.ruby_toggle_file(_("lib/zero.rb")) 33 | end 34 | 35 | def test_test_file__exist__libone_testone 36 | create "lib/one/one.rb", "test/one/test_one.rb" 37 | rtf = RubyToggleFile.new 38 | assert_equal _("test/one/test_one.rb"), rtf.ruby_toggle_file(_("lib/one/one.rb")) 39 | end 40 | 41 | def test_test_file__exist__libtwo_test 42 | create "lib/two/two.rb", "test/test_two.rb" 43 | rtf = RubyToggleFile.new 44 | assert_equal _("test/test_two.rb"), rtf.ruby_toggle_file(_("lib/two/two.rb")) 45 | end 46 | 47 | def test_test_file__exist__top_test 48 | create "three.rb", "test_three.rb" 49 | rtf = RubyToggleFile.new 50 | assert_equal _("test_three.rb"), rtf.ruby_toggle_file(_("three.rb")) 51 | end 52 | 53 | def test_test_file__not_exist__top 54 | create "four.rb" 55 | rtf = RubyToggleFile.new 56 | assert_equal _("test_four.rb"), rtf.ruby_toggle_file(_("four.rb")) 57 | end 58 | 59 | def test_test_file__not_exist__lib 60 | create "lib/five.rb" 61 | rtf = RubyToggleFile.new 62 | assert_equal _("test/test_five.rb"), rtf.ruby_toggle_file(_("lib/five.rb")) 63 | end 64 | 65 | def test_test_file__not_exist__libsixsix 66 | create "lib/six/six/six.rb" 67 | rtf = RubyToggleFile.new 68 | assert_equal _("test/six/six/test_six.rb"), rtf.ruby_toggle_file(_("lib/six/six/six.rb")) 69 | end 70 | 71 | def test_implementation_file__exist__lib_test 72 | create "lib/zero.rb", "test/test_zero.rb" 73 | rtf = RubyToggleFile.new 74 | assert_equal _("lib/zero.rb"), rtf.ruby_toggle_file(_("test/test_zero.rb")) 75 | end 76 | 77 | def test_implementation_file__exist__libone_testone 78 | create "lib/one/one.rb", "test/one/test_one.rb" 79 | rtf = RubyToggleFile.new 80 | assert_equal _("lib/one/one.rb"), rtf.ruby_toggle_file(_("test/one/test_one.rb")) 81 | end 82 | 83 | def test_implementation_file__exist__libtwo_test 84 | create "lib/two/two.rb", "test/test_two.rb" 85 | rtf = RubyToggleFile.new 86 | assert_equal _("lib/two/two.rb"), rtf.ruby_toggle_file(_("test/test_two.rb")) 87 | end 88 | 89 | def test_implementation_file__exist__top_test 90 | create "three.rb", "test_three.rb" 91 | rtf = RubyToggleFile.new 92 | assert_equal _("three.rb"), rtf.ruby_toggle_file(_("test_three.rb")) 93 | end 94 | 95 | def test_implementation_file__not_exist__none_top 96 | create "test_seven.rb" 97 | rtf = RubyToggleFile.new 98 | assert_equal _("seven.rb"), rtf.ruby_toggle_file(_("test_seven.rb")) 99 | end 100 | 101 | def test_implementation_file__not_exist__none_test 102 | create "test/test_eight.rb" 103 | rtf = RubyToggleFile.new 104 | assert_equal _("lib/eight.rb"), rtf.ruby_toggle_file(_("test/test_eight.rb")) 105 | end 106 | 107 | def test_implementation_file__not_exist__none_testninenine 108 | create "test/nine/nine/nine.rb" 109 | rtf = RubyToggleFile.new 110 | assert_equal _("lib/nine/nine/nine.rb"), rtf.ruby_toggle_file(_("test/nine/nine/test_nine.rb")) 111 | end 112 | 113 | ########################################################################### 114 | # Rails test # 115 | ########################################################################### 116 | def test_test_file__rails_controllers 117 | create "app/controllers/c.rb", "test/functional/c_test.rb" 118 | rtf = RubyToggleFile.new 119 | assert_equal _("test/functional/c_test.rb"), rtf.ruby_toggle_file(_("app/controllers/c.rb")) 120 | end 121 | 122 | def test_test_file__rails_models 123 | create "app/models/m.rb", "test/unit/m_test.rb" 124 | rtf = RubyToggleFile.new 125 | assert_equal _("test/unit/m_test.rb"), rtf.ruby_toggle_file(_("app/models/m.rb")) 126 | end 127 | 128 | def test_test_file__rails_lib 129 | create "lib/l.rb", "test/unit/test_l.rb", "app/models/m.rb" 130 | rtf = RubyToggleFile.new 131 | assert_equal _("test/unit/test_l.rb"), rtf.ruby_toggle_file(_("lib/l.rb")) 132 | end 133 | 134 | 135 | def test_implementation_file__rails_controllers 136 | create "app/controllers/c.rb", "test/functional/c_test.rb" 137 | rtf = RubyToggleFile.new 138 | assert_equal _("app/controllers/c.rb"), rtf.ruby_toggle_file(_("test/functional/c_test.rb")) 139 | end 140 | 141 | def test_implementation_file__rails_models 142 | create "app/models/m.rb", "test/unit/m_test.rb" 143 | rtf = RubyToggleFile.new 144 | assert_equal _("app/models/m.rb"), rtf.ruby_toggle_file(_("test/unit/m_test.rb")) 145 | end 146 | 147 | def test_implementation_file__rails_lib 148 | create "lib/l.rb", "test/unit/test_l.rb", "app/models/m.rb" 149 | rtf = RubyToggleFile.new 150 | assert_equal _("lib/l.rb"), rtf.ruby_toggle_file(_("test/unit/test_l.rb")) 151 | end 152 | end 153 | 154 | 155 | class TestRunHooksWithArgsUntilSuccess < Test::Unit::TestCase 156 | def m001(x) nil end 157 | private 158 | def m002(x) false end 159 | def m003(x) 100*x end 160 | def m004(x) 200 end 161 | 162 | public 163 | def test_run_hooks_with_args_until_success__m003 164 | assert_equal 1000, run_hooks_with_args_until_success(/^m\d+$/, 10) 165 | end 166 | 167 | def test_run_hooks_with_args_until_success__m001 168 | assert_nil run_hooks_with_args_until_success(/^m001$/, 10) 169 | end 170 | 171 | def test_run_hooks_with_args_until_success__m004 172 | assert_equal 200, run_hooks_with_args_until_success(/^m004$/, 10) 173 | end 174 | end 175 | -------------------------------------------------------------------------------- /test/test_xmpfilter.rb: -------------------------------------------------------------------------------- 1 | 2 | require 'test/unit' 3 | $: << ".." << "../lib" 4 | require "rcodetools/xmpfilter" 5 | require 'rubygems' 6 | require 'mocha' 7 | 8 | class TestXMPFilter < Test::Unit::TestCase 9 | include Rcodetools 10 | def test_extract_data__results 11 | marker = XMPFilter::MARKER 12 | str = <<-EOF 13 | #{marker}[1] => Fixnum 42 14 | #{marker}[1] => Fixnum 0 15 | #{marker}[1] ==> var 16 | #{marker}[1] ==> var2 17 | #{marker}[4] ==> var3 18 | #{marker}[2] ~> some exception 19 | #{marker}[10] => Fixnum 42 20 | EOF 21 | xmp = XMPFilter.new 22 | data = xmp.extract_data(str) 23 | assert_equal([[1, [["Fixnum", "42"], ["Fixnum", "0"]]], [10, [["Fixnum", "42"]]]], data.results.sort) 24 | end 25 | 26 | def test_extract_data__exceptions 27 | marker = XMPFilter::MARKER 28 | str = <<-EOF 29 | #{marker}[1] => Fixnum 42 30 | #{marker}[1] => Fixnum 0 31 | #{marker}[1] ==> var 32 | #{marker}[1] ==> var2 33 | #{marker}[4] ==> var3 34 | #{marker}[2] ~> some exception 35 | #{marker}[10] => Fixnum 42 36 | EOF 37 | xmp = XMPFilter.new 38 | data = xmp.extract_data(str) 39 | assert_equal([[2, ["some exception"]]], data.exceptions.sort) 40 | end 41 | 42 | def test_extract_data__bindings 43 | marker = XMPFilter::MARKER 44 | str = <<-EOF 45 | #{marker}[1] => Fixnum 42 46 | #{marker}[1] => Fixnum 0 47 | #{marker}[1] ==> var 48 | #{marker}[1] ==> var2 49 | #{marker}[4] ==> var3 50 | #{marker}[2] ~> some exception 51 | #{marker}[10] => Fixnum 42 52 | EOF 53 | xmp = XMPFilter.new 54 | data = xmp.extract_data(str) 55 | assert_equal([[1, ["var", "var2"]], [4, ["var3"]]], data.bindings.sort) 56 | end 57 | 58 | def test_interpreter_command 59 | xmp = XMPFilter.new(:interpreter=>"ruby", :detect_rct_fork => false) 60 | assert_equal(%w[ruby -w], xmp.interpreter_command) 61 | end 62 | 63 | def test_interpreter_command_detect_rct_fork 64 | Fork.stubs(:run?).returns true 65 | xmp = XMPFilter.new(:interpreter=>"ruby", :detect_rct_fork => true) 66 | assert_equal(%w[ruby -S rct-fork-client], xmp.interpreter_command) 67 | end 68 | 69 | def test_interpreter_command_use_rbtest 70 | xmp = XMPFilter.new(:interpreter=>"ruby", :use_rbtest => true) 71 | assert_equal(%w[ruby -S rbtest], xmp.interpreter_command) 72 | end 73 | 74 | def test_initialize__test_script_1 75 | XMPFilter.any_instance.stubs(:safe_require_code).returns("require 'test/unit'") 76 | xmp = XMPFilter.new(:test_script=>"/path/to/test/test_ruby_toggle_file.rb", 77 | :test_method=>"test_implementation_file_file_exist", 78 | :filename=>"/path/to/lib/ruby_toggle_file.rb") 79 | 80 | evals_expected = [ 81 | %q!$LOADED_FEATURES << "ruby_toggle_file.rb"!, 82 | %q!require 'test/unit'!, 83 | %q!load "/path/to/test/test_ruby_toggle_file.rb"!, 84 | %q!Test::Unit::AutoRunner.run(false, nil, ["-n", "test_implementation_file_file_exist"])! 85 | ] 86 | assert_equal evals_expected, xmp.instance_variable_get(:@evals) 87 | end 88 | 89 | def test_initialize__test_script_2 90 | XMPFilter.any_instance.stubs(:safe_require_code).returns("require 'test/unit'") 91 | xmp = XMPFilter.new(:test_script=>"/path/to/test_ruby_toggle_file.rb", 92 | :test_method=>"test_implementation_file_file_exist", 93 | :filename=>"/path/to/ruby_toggle_file.rb") 94 | 95 | evals_expected = [ 96 | %q!$LOADED_FEATURES << "ruby_toggle_file.rb"!, 97 | %q!require 'test/unit'!, 98 | %q!load "/path/to/test_ruby_toggle_file.rb"!, 99 | %q!Test::Unit::AutoRunner.run(false, nil, ["-n", "test_implementation_file_file_exist"])! 100 | ] 101 | assert_equal evals_expected, xmp.instance_variable_get(:@evals) 102 | end 103 | 104 | def test_initialize__test_script_3 105 | test_script = File.join(File.dirname(__FILE__), "data/sample_test_script.rb") 106 | filename = File.join(File.dirname(__FILE__), "data/sample.rb") 107 | XMPFilter.any_instance.stubs(:safe_require_code).returns("require 'test/unit'") 108 | xmp = XMPFilter.new(:test_script=>test_script, :test_method=>"4", :filename=>filename) 109 | 110 | evals_expected = [ 111 | %q!$LOADED_FEATURES << "sample.rb"!, 112 | %q!require 'test/unit'!, 113 | %Q!load #{test_script.dump}!, 114 | %q!Test::Unit::AutoRunner.run(false, nil, ["-n", "test_sample0"])! 115 | ] 116 | assert_equal evals_expected, xmp.instance_variable_get(:@evals) 117 | end 118 | 119 | def test_initialize__test_script__filename_eq_test_script 120 | test_script = File.join(File.dirname(__FILE__), "data/sample_test_script.rb") 121 | filename = test_script 122 | xmp = XMPFilter.new(:test_script=>test_script, :test_method=>"4", :filename=>filename) 123 | 124 | evals_expected = [ 125 | %q!Test::Unit::AutoRunner.run(false, nil, ["-n", "test_sample0"])! 126 | ] 127 | assert_equal evals_expected, xmp.instance_variable_get(:@evals) 128 | end 129 | 130 | def test_get_test_method_from_lineno 131 | file = File.join(File.dirname(__FILE__), "data/sample_test_script.rb") 132 | xmp = XMPFilter.new 133 | assert_equal("test_sample0", xmp.get_test_method_from_lineno(file, 4)) 134 | assert_equal("test_sample1", xmp.get_test_method_from_lineno(file, 7)) 135 | assert_equal("test_sample1", xmp.get_test_method_from_lineno(file, 8)) 136 | assert_equal(nil, xmp.get_test_method_from_lineno(file, 1)) 137 | end 138 | 139 | # Use methods to avoid confusing syntax highlighting 140 | def beg() "=begin" end 141 | def ed() "=end" end 142 | 143 | def test_s_detect_rbtest_1 144 | rbtest_script_1 = < true} 152 | assert_equal true, XMPFilter.detect_rbtest(rbtest_script_1, opts) 153 | assert_equal true, opts[:use_rbtest] 154 | opts = {:detect_rbtest => false} 155 | assert_equal false, XMPFilter.detect_rbtest(rbtest_script_1, opts) 156 | assert_equal false, opts[:use_rbtest] 157 | opts = {:detect_rbtest => false, :use_rbtest => true} 158 | assert_equal true, XMPFilter.detect_rbtest(rbtest_script_1, opts) 159 | assert_equal true, opts[:use_rbtest] 160 | end 161 | 162 | def test_s_detect_rbtest_2 163 | rbtest_script_2 = < true} 170 | assert_equal true, XMPFilter.detect_rbtest(rbtest_script_2, opts) 171 | assert_equal true, opts[:use_rbtest] 172 | opts = {:detect_rbtest => false} 173 | assert_equal false, XMPFilter.detect_rbtest(rbtest_script_2, opts) 174 | assert_equal false, opts[:use_rbtest] 175 | end 176 | 177 | def test_s_detect_rbtest_3 178 | no_rbtest_script = < true} 183 | assert_equal false, XMPFilter.detect_rbtest(no_rbtest_script, opts) 184 | assert_equal false, opts[:use_rbtest] 185 | opts = {:detect_rbtest => false} 186 | assert_equal false, XMPFilter.detect_rbtest(no_rbtest_script, opts) 187 | assert_equal false, opts[:use_rbtest] 188 | end 189 | 190 | end 191 | 192 | -------------------------------------------------------------------------------- /test/test_xmptestunitfilter.rb: -------------------------------------------------------------------------------- 1 | 2 | require 'test/unit' 3 | $: << ".." << "../lib" 4 | require "rcodetools/xmptestunitfilter" 5 | 6 | class TestXMPTestUnitFilter < Test::Unit::TestCase 7 | include Rcodetools 8 | 9 | ANNOTATION_VAR_INFERENCE_INPUT = < 15 | arr.last # \=> 16 | EOF 17 | ANNOTATION_VAR_INFERENCE_OUTPUT = <]\", arr.inspect) 25 | assert_equal(x, arr.last) 26 | assert_kind_of(X, arr.last) 27 | assert_equal(\"#\", arr.last.inspect) 28 | EOF 29 | 30 | def test_annotation_var_inference 31 | xmp = XMPTestUnitFilter.new 32 | assert_equal(ANNOTATION_VAR_INFERENCE_OUTPUT, 33 | xmp.annotate(ANNOTATION_VAR_INFERENCE_INPUT).join("")) 34 | end 35 | 36 | def test_equality_assertions 37 | xmp = XMPTestUnitFilter.new 38 | assert_equal(["a = 1\n", "assert_equal(1, a)"], xmp.annotate("a = 1\na # \=>")) 39 | assert_equal(["a = {1,2}\n", "assert_equal({1=>2}, a)"], 40 | xmp.annotate("a = {1,2}\na # \=>")) 41 | assert_equal(["a = [1,2]\n", "assert_equal([1, 2], a)"], 42 | xmp.annotate("a = [1,2]\na # \=>")) 43 | assert_equal(["a = 'foo'\n", "assert_equal(\"foo\", a)"], 44 | xmp.annotate("a = 'foo'\na # \=>")) 45 | assert_equal(["a = 1.0\n", "assert_in_delta(1.0, a, 0.0001)"], 46 | xmp.annotate("a = 1.0\na # \=>")) 47 | end 48 | 49 | def test_raise_assertion 50 | code = < 53 | EOF 54 | xmp = XMPTestUnitFilter.new 55 | assert_equal(["class NoGood < Exception; end\n", 56 | "assert_raise(NoGood){raise NoGood}\n"], xmp.annotate(code)) 57 | end 58 | 59 | def test_assert_nil 60 | xmp = XMPTestUnitFilter.new 61 | assert_equal(["a = nil\n", "assert_nil(a)"], xmp.annotate("a = nil\na # \=>")) 62 | end 63 | 64 | def test_poetry_mode 65 | code = < 68 | a = 1.0 69 | a # \=> 70 | raise "foo" # \=> 71 | a = nil 72 | a # \=> 73 | EOF 74 | output = < false) 84 | assert_equal(output, xmp.annotate(code).join) 85 | end 86 | end 87 | -------------------------------------------------------------------------------- /test/tmp_functional.rb: -------------------------------------------------------------------------------- 1 | require 'test/unit' 2 | 3 | module TestFunctional 4 | DIR = File.expand_path(File.dirname(__FILE__)) 5 | LIBDIR = File.expand_path(DIR + '/../lib') 6 | 7 | module DefineFunctionalTests 8 | def define_functional_tests(bin, exec, tests) 9 | tests.each_pair do |test, opts| 10 | define_method("test_#{test}") do 11 | 12 | output = `ruby -I#{LIBDIR} #{exec} #{opts.join(" ")} #{DIR}/data/#{test}-input.rb` 13 | outputfile = "#{DIR}/data/#{test}-output.rb" 14 | taffile = "#{DIR}/data/#{bin}/#{test}.taf" 15 | open(taffile, "w") do |f| 16 | f.puts "==========" 17 | f.puts test 18 | f.puts "==========" 19 | f.puts bin + " " + opts.join(" ") 20 | f.puts "==========" 21 | f.puts File.read("#{DIR}/data/#{test}-input.rb") 22 | f.puts "==========" 23 | f.puts File.read("#{DIR}/data/#{test}-output.rb") 24 | end 25 | # assert_equal(File.read(outputfile), output) 26 | end 27 | end 28 | end 29 | end 30 | 31 | class TestXmpfilter < Test::Unit::TestCase 32 | extend DefineFunctionalTests 33 | tests = { 34 | :simple_annotation => [], :unit_test => ["-u"], :rspec => ["-s"], 35 | :no_warnings => ["--no-warnings"], :bindings => ["--poetry", "-u"], 36 | :add_markers => ["-m"], :unit_test_rbtest => ["-u", "--rbtest"], 37 | :unit_test_detect_rbtest => ["-u", "--detect-rbtest"], 38 | :unit_test_detect_rbtest2 => ["--detect-rbtest"], 39 | } 40 | define_functional_tests "xmpfilter", File.expand_path(DIR + '/../bin/xmpfilter'), tests 41 | end 42 | 43 | class TestRctComplete < Test::Unit::TestCase 44 | extend DefineFunctionalTests 45 | tests = { 46 | :completion_rbtest => [ "--rbtest", "--line=6" ], 47 | :completion_detect_rbtest => [ "--detect-rbtest", "--line=6" ], 48 | :completion_detect_rbtest2 => [ "--detect-rbtest", "--line=1" ], 49 | } 50 | define_functional_tests "rct-complete", File.expand_path(DIR + '/../bin/rct-complete'), tests 51 | end 52 | 53 | class TestRctDoc < Test::Unit::TestCase 54 | extend DefineFunctionalTests 55 | tests = { 56 | :doc_rbtest => [ "--rbtest", "--line=6" ], 57 | :doc_detect_rbtest => [ "--detect-rbtest", "--line=1" ], 58 | :doc_detect_rbtest2 => [ "--detect-rbtest", "--line=6" ], 59 | } 60 | define_functional_tests "rct-doc", File.expand_path(DIR + '/../bin/rct-doc'), tests 61 | end 62 | 63 | 64 | # Other tests are in test_run.rb 65 | class TestRctCompleteTDC < Test::Unit::TestCase 66 | test = :completion_in_method 67 | inputfile = "#{DIR}/data/#{test}-input.rb" 68 | outputfile = "#{DIR}/data/#{test}-output.rb" 69 | test_script = "#{DIR}/data/#{test}-test.rb" 70 | common_opts = ["--filename #{inputfile}", "--line 2"] 71 | right_output = File.read(outputfile) 72 | wrong_output = "\n" 73 | 74 | tests = { 75 | :completion_in_method__testscript => 76 | [ common_opts + ["-t #{test_script}"], right_output ], 77 | :completion_in_method__testmethod => 78 | [ common_opts + ["-t #{test_script}@test_fooz"], right_output ], 79 | :completion_in_method__wrong_testmethod => 80 | [ common_opts + ["-t #{test_script}@test_NOT_FOUND"], wrong_output ], 81 | } 82 | exec = File.expand_path(DIR + '/../bin/rct-complete') 83 | # tests.each_pair do |test, (opts, expected)| 84 | # define_method("test_#{test}") do 85 | # output = `ruby -I#{LIBDIR} #{exec} #{opts.join(" ")} #{inputfile}` 86 | 87 | # taffile = "#{DIR}/data/#{bin}/#{test}.taf" 88 | # open(taffile, "w") do |f| 89 | # f.puts "==========" 90 | # f.puts test 91 | # f.puts "==========" 92 | # f.puts bin + " " + opts.join(" ") 93 | # f.puts "==========" 94 | # f.puts File.read("#{DIR}/data/#{test}-input.rb") 95 | # f.puts "==========" 96 | # f.puts File.read("#{DIR}/data/#{test}-output.rb") 97 | # end 98 | # end 99 | # end 100 | 101 | test=:completion_in_method__testscript 102 | define_method("test_#{test}") do 103 | taffile = "#{DIR}/data/rct-complete-TDC/completion_in_method__testscript.taf" 104 | open(taffile, "w") do |f| 105 | opts = tests[test] 106 | f.puts "==========" 107 | f.puts test 108 | f.puts "==========" 109 | f.puts "rct-complete " + opts.join(" ") 110 | f.puts "==========" 111 | test0 = :completion_in_method 112 | f.puts File.read("#{DIR}/data/#{test0}-input.rb") 113 | f.puts "==========" 114 | f.puts File.read("#{DIR}/data/#{test0}-output.rb") 115 | f.puts "==========" 116 | f.puts File.read("#{DIR}/data/#{test0}-test.rb") 117 | end 118 | 119 | end 120 | 121 | test=:completion_in_method__testmethod 122 | define_method("test_#{test}") do 123 | taffile = "#{DIR}/data/rct-complete-TDC/completion_in_method__testmethod.taf" 124 | open(taffile, "w") do |f| 125 | opts = tests[test] 126 | f.puts "==========" 127 | f.puts test 128 | f.puts "==========" 129 | f.puts "rct-complete " + opts.join(" ") 130 | f.puts "==========" 131 | test0 = :completion_in_method 132 | f.puts File.read("#{DIR}/data/#{test0}-input.rb") 133 | f.puts "==========" 134 | f.puts File.read("#{DIR}/data/#{test0}-output.rb") 135 | f.puts "==========" 136 | f.puts File.read("#{DIR}/data/#{test0}-test.rb") 137 | end 138 | 139 | end 140 | 141 | test=:completion_in_method__wrong_testmethod 142 | define_method("test_#{test}") do 143 | taffile = "#{DIR}/data/rct-complete-TDC/completion_in_method__wrong_testmethod.taf" 144 | open(taffile, "w") do |f| 145 | opts = tests[test] 146 | f.puts "==========" 147 | f.puts test 148 | f.puts "==========" 149 | f.puts "rct-complete " + opts.join(" ") 150 | f.puts "==========" 151 | test0 = :completion_in_method 152 | f.puts File.read("#{DIR}/data/#{test0}-input.rb") 153 | f.puts "==========" 154 | f.puts 155 | f.puts "==========" 156 | f.puts File.read("#{DIR}/data/#{test0}-test.rb") 157 | end 158 | 159 | end 160 | 161 | end 162 | end 163 | -------------------------------------------------------------------------------- /test/tmp_run.rb: -------------------------------------------------------------------------------- 1 | require 'test/unit' 2 | require 'rcodetools/xmpfilter' 3 | require 'rcodetools/xmptestunitfilter' 4 | require 'rcodetools/completion' 5 | require 'rcodetools/doc' 6 | require 'rcodetools/options' 7 | require 'stringio' 8 | 9 | class TestRun < Test::Unit::TestCase 10 | include Rcodetools 11 | DIR = File.expand_path(File.dirname(__FILE__)) 12 | 13 | tests = { 14 | # :rspec_poetry => {:klass => XMPRSpecFilter, :interpreter => "spec", :use_parentheses => false}, 15 | :rspec_poetry => ["xmpfilter", "-s --poetry"], 16 | # :unit_test_poetry => {:klass => XMPTestUnitFilter, :use_parentheses => false}, 17 | :unit_test_poetry => ["xmpfilter", "-u --poetry"], 18 | 19 | # :completion => {:klass => XMPCompletionFilter, :lineno => 1}, 20 | :completion => ["rct-complete", "-C --line=1"], 21 | # :completion_emacs => {:klass => XMPCompletionEmacsFilter, :lineno => 1}, 22 | :completion_emacs => ["rct-complete", "--completion-emacs --line=1"], 23 | # :completion_emacs_icicles => {:klass => XMPCompletionEmacsIciclesFilter, :lineno => 1}, 24 | :completion_emacs_icicles => ["rct-complete","--completion-emacs-icicles --line=1"], 25 | # :completion_class_info => {:klass => XMPCompletionClassInfoFilter, :lineno => 1}, 26 | :completion_class_info => ["rct-complete", "--completion-class-info --line=1"], 27 | # :completion_class_info_no_candidates => {:klass => XMPCompletionClassInfoFilter, :lineno => 1}, 28 | :completion_class_info_no_candidates => ["rct-complete", "--completion-class-info --line=1"], 29 | 30 | # :doc => {:klass => XMPDocFilter, :lineno => 1}, 31 | # :refe => {:klass => XMPReFeFilter, :lineno => 1}, 32 | # :ri => {:klass => XMPRiFilter, :lineno => 1}, 33 | # :ri_emacs => {:klass => XMPRiEmacsFilter, :lineno => 1}, 34 | # :ri_vim => {:klass => XMPRiVimFilter, :lineno => 1}, 35 | :doc => ["rct-doc", "-D --line=1"], 36 | :refe => ["rct-doc", "--refe --line=1"], 37 | :ri => ["rct-doc", "--ri --line=1"], 38 | :ri_emacs => ["rct-doc", "--ri-emacs --line=1"], 39 | :ri_vim => ["rct-doc", "--ri-vim --line=1"], 40 | 41 | } 42 | DIR = File.expand_path(File.dirname(__FILE__)) 43 | LIBDIR = File.expand_path(DIR + '/../lib') 44 | 45 | tests.each_pair do |test, (bin,opts)| 46 | define_method("test_#{test}") do 47 | inputfile = "#{DIR}/data/#{test}-input.rb" 48 | outputfile = "#{DIR}/data/#{test}-output.rb" 49 | 50 | # exec = File.expand_path(DIR + '/../bin/xmpfilter') 51 | # output = `ruby -I#{LIBDIR} #{exec} #{opts} #{DIR}/data/#{test}-input.rb` 52 | # outputfile = "#{DIR}/data/#{test}-output.rb" 53 | taffile = "#{DIR}/data/#{bin}/#{test}.taf" 54 | open(taffile, "w") do |f| 55 | f.puts "==========" 56 | f.puts test 57 | f.puts "==========" 58 | f.puts bin + " " + opts 59 | f.puts "==========" 60 | f.puts File.read("#{DIR}/data/#{test}-input.rb") 61 | f.puts "==========" 62 | f.puts File.read("#{DIR}/data/#{test}-output.rb") 63 | end 64 | end 65 | end 66 | end 67 | --------------------------------------------------------------------------------