| =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} | |