
= Overview

Ruby is very dynamic language, therefore it is impossible to do
accurate completion without executing script.  While executing script
from start to cursor point is often dangerous, executing unit test
script covering current point is SAFE.  I call this methodology
`Test-Driven Completion' (TDC).

As I have already stated in README, browsing documentation of method
(rct-doc) is almost identical operation to completion.  This
discussion is applicable to rct-doc.

= Why TDD Is Needed

In the following code snippet:

  File.unlink a_file
  File. <-

If you complete after `File.', rct-complete actually deletes a_file.
Normally it is unpleasant.
In real-life development, side-effect is inevitable.

In the foo method which are not called:

  def foo
    1. <-
  end

If the code does not call foo, rct-complete cannot do any completions.
Before TDC, if you want to do completion in methods, you have to write
method call and remove it after completion. Too useless!!

= Messianic Unit Test Script

Recently Test-Driven Development (TDD) is widespread.  Many developers
write unit tests.  Fortunately Ruby's unit tester, Test::Unit, is
sophisticated enough to test one test method.  Unit tests are
self-enclosed: they must tear down resources, so executing unit tests
are SAFE.  TDC uses unit test to do completion.

= TDC Methodology

(1) Switch to unit test script.
(2) Write a test for target method.
(3) Switch to implementation script.
(4) You can write target method WITH COMPLETION!
(5) Back to (1)

TDC methodology is almost identical to TDD. TDC is very easy for TDDers.

= TDC With Example

For simplicity, suppose that you are unfamiliar with Time class and
you want to write a method to format date string.

The directory structure and file contents is following:

  /tmp/mylib0/
  /tmp/mylib0/lib/
     mylib0.rb
  /tmp/mylib0/test/
     test_mylib0.rb

  List: mylib0.rb
  # contrived example of long-runtime method
  def mysleep(x)
    sleep x
  end

  def mytime(tm)

  end


  List: test_mylib0.rb
  require 'test/unit'
  require 'mylib0'
  class TestMylib0 < Test::Unit::TestCase
    def test_0_mysleep
      s = Time.now
      mysleep 3.0
      e = Time.now
      assert_in_delta 3.0, e-s, 0.01
    end

    def test_1_mytime

    end
  end

These sample files are in demo/ directory.


== Switch to unit test script.

TDC starts with writing unit test as TDD does.
Open test_mylib0.rb.

== Write a test for target method.

Suppose that you want to write mytime method and test_1_mytime test
method, and that you want to experiment Time class first (before
forming an assertion).

In TDC, you do not have to write an assertion first: just write only a
method call.  If you are familiar with Time class, you are free to
write an assertion, of course.

    def test_1_mytime
      mytime(Time.now)
    end

At this time, the cursor position is in test_1_mytime test method.

== Switch to implementation script.

Open mylib0.rb with the `ruby-toggle-file' script.  For example, in Emacs use
the `ruby-toggle-buffer' command, and in vim the <localleader>t (by default
\t) binding.  Since in TDD/TDC you often switch between the test and the
implementation, it is much handier than typing the filename manually.

The rct-complete uses latest-selected test script as TDC test script
and test method at cursor position as TDC test method.  In this case,
test_mylib0.rb is TDC test script and test_1_mytime is TDC test
method.  If the cursor position of test_mylib0.rb is at the top,
rct-complete executes whole test methods in test_mylib0.rb.  Therefore
latency of completion is longer.

== You can write target method WITH COMPLETION!

Fill mytime method.

  def mytime(tm)
    tm.
  end

Do completion after `tm.'. Here! Your editor is listing methods `tm'
accepts!!  If your editor has help-on-candidate mechanism (eg. Emacs +
Icicles), you would see documentation of each listed method.

Then you find `Time#strftime' method. Type `str' and do completion.

  def mytime(tm)
    tm.strftime 
  end

Usage is... use `rct-doc' (in Emacs, `rct-ri') after `strftime'.

After you are familiar with Time class, switch to test script and write assertions.

= When Modifying Another Method

If you want to modify already-written method, setting cursor position
of corresponding test script to corresponding test method is better.
It tells rct-complete new test script and test method, so you can do
completion in the new method.
