=begin

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

Scans java test source files, recursively from the current directory,
and produces a list of test metods sorted by specification line number.

The implementation makes heavy use of my scant knowledge of regex.  I'll
comeback and clean this up as time allows.

Assumes a test comment convention like this:

    /**
     * Lines 410,411,412,413:
     * <p>
     * A method of a conversational interface may be marked with an
     * "@EndsConversation" annotation. Once a method marked with
     * "@EndsConversation" has been called, the conversation between client and
     * service provider is at an end, which implies no further methods may be
     * called on that service within the *same* conversation.
     */
    @Test
    public void atEndsConversation1() throws Exception {

Example command line usage
>ruby processcomments.rb > comment_scan.txt

Current output is formatted for a cwiki page and can be directly pasted to a blank page

Some TODO's:
  Add logic to process number ranges such as "Lines 523-556" or "Lines 523 to 556"
=end
class TestMethod
  
  attr_accessor :lines_tested, :first_line_tested
  
  def initialize(text, parent)
    @text = text
    @parent = parent
    @lines_tested = init_lines_tested
    @first_line_tested = @lines_tested.first
  end  
  
  #Define sort criteria
  def <=>(test_method)  
    @first_line_tested.<=>(test_method.first_line_tested)  
  end  
  
  def name
    regex = /void\s*\S*\(\) /
    str = @text[regex]
    str.sub(/void\s*/, '')
  end
  
  def init_lines_tested
    lines_regex = /Line.*?$/
    lines_array = @text.scan(lines_regex)
    nums_regex = /\d{1,4}/
    line_numbers = Array.new
    lines_array.each do |line_text|
      number_strings =line_text.scan(nums_regex)
      number_strings.each {|num_string| line_numbers<<num_string.to_i}
    end
    line_numbers
  end
  
  def lines_tested_string
    lts = String.new
    lines_tested.each {|n| lts = lts +"," + n.to_s }
    lts[1..lts.length]
  end
  
  def ignore_line
    @text[/^\s*@Ignore.*/]
  end
  
  def jira
    result = ignore_line
    result = result[/\d{4,5}/] 
    result ?  "T-" + result : "x"
  end
  
  def ignore_string
    ignore_line ?  jira : ""
  end
  
  def package_name
    @parent.package_name
  end
  
  def testcase_name
    @parent.testcase_name
  end
  
  def long_name
    self.package_name + "." + testcase_name + "." + self.name
  end
  
  def to_s
    long_name  + "\n" + "Lines tested: " + lines_tested_string + "\n\n"
  end
  
  def to_cwiki_s
    "|" + lines_tested_string + "|" + long_name + "|" + ignore_string + "|\n"
  end
end

class TestCase
  attr_accessor :text, :test_methods
  
  def initialize(text)
    @text = text
    @test_methods = Array.new
    create_test_methods
  end  
  
  def create_test_methods
    regex = /\/\*\*\W*?$\W*?Line.*?\{/m
    test_method_text_array = text.scan(regex)
    test_method_text_array.each do |t| 
      @test_methods<<TestMethod.new(t, self)
      $num_test_methods +=1
    end
  end
  
  def package_name
    line = @text[/pack.*$/]
    line.sub!(/package /, '')
    line.sub(/;/, '')
  end
  
  def testcase_name
    text[/\S*TestCase/]
  end
end
  
def process_file(fn)
  text = String.new
  File.open(fn) { |f|  text = f.read } 
  $testcases << TestCase.new(text)
end

def spec_tested (dir_pwd)
  subfolder_name = dir_pwd[/\/[^\/\\]*$/]
  subfolder_name = subfolder_name[1..subfolder_name.length-1]
  result = case subfolder_name
    when "java-api" : "SCA Java Common Annotations and APIs V1.00"
    when "wsbinding" : "SCA Web Services Binding V1.00"
    else "Unknown!"
    end
end

$num_files_processed = $num_test_methods = 0
$testcases = Array.new
svn_info = `svn info`
svn_revision = svn_info[/Revision: \d*/]

Dir["**/*TestCase.java"].each do |filename|
  process_file(filename)
   $num_files_processed += 1
end

all_test_methods = Array.new
$testcases.each do |tc| 
  tc.test_methods.each {|m| all_test_methods<<m}
end

#confluence wiki output
puts "Content generated by /vtest/processcomments.rb"
puts "h1. " + spec_tested(Dir.pwd) + " - Test map"
puts "h3. Test case files scanned " + Date.today.to_s + " (svn:" + svn_revision + ")"
puts "* Total files processed = #{$num_files_processed}"
puts "* Number of test cases = #{$testcases.length}"
puts "* Number of test methods = #{$num_test_methods}"

puts "||Specification Line Numbers|| package/testcase/method ||ignored||"
all_test_methods.sort.each {|tm| puts tm.to_cwiki_s}




