All Downloads are FREE. Search and download functionalities are using the official Maven repository.

groovy.util.JavadocAssertionTestBuilder.groovy Maven / Gradle / Ivy

There is a newer version: 3.9
Show newest version
/*
 * Copyright 2003-2009 the original author or authors.
 *
 * Licensed 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.
 */
package groovy.util

import java.util.regex.Pattern

/**
 * JavadocAssertionTestBuilder will dynamically create a test cases from Groovy assertions placed within
 * the Javadoc comments of a source file. Assertions should be placed within an html tag with a class="groovyTestCase"
 * attribute assignment. Example:
 * 
<pre class="groovyTestCase"> assert "example".size() == 7 </pre>
* * @author Merlyn Albery-Speyer */ class JavadocAssertionTestBuilder { private static Pattern javadocPattern = Pattern.compile( /(?ims)\/\*\*.*?\*\// ) private static Pattern assertionPattern = Pattern.compile( /(?ims)<([a-z]+)\s+class\s*=\s*['"]groovyTestCase['"]\s*>.*?<\s*\/\s*\1>/ ) Class buildTest(String filename, String code) { Class test = null List assertionTags = getAssertionTags(code); if (assertionTags) { String testName = getTestName(filename) Map lineNumberToAssertions = getLineNumberToAssertionsMap(code, assertionTags) List testMethods = getTestMethods(lineNumberToAssertions, filename) String testCode = getTestCode(testName, testMethods) test = createClass(testCode) } return test } private List getAssertionTags(String code) { List assertions = new ArrayList() code.eachMatch(javadocPattern) { javadoc -> assertions.addAll(javadoc.findAll(assertionPattern)) } return assertions } private String getTestName(String filename) { String filenameWithoutPath = new File(filename).name String testName = filenameWithoutPath.substring(0, filenameWithoutPath.lastIndexOf(".")) + "JavadocAssertionTest" return testName } private Map getLineNumberToAssertionsMap(String code, List assertionTags) { Map lineNumberToAssertions = [:] as LinkedHashMap int codeIndex = 0 assertionTags.each { tag -> codeIndex = code.indexOf(tag, codeIndex) int lineNumber = code.substring(0, codeIndex).findAll("(?m)^").size() codeIndex += tag.size() String assertion = getAssertion(tag) lineNumberToAssertions.get(lineNumber, []) << assertion } return lineNumberToAssertions } private String getAssertion(String tag) { String tagInner = tag.substring(tag.indexOf(">")+1, tag.lastIndexOf("<")) String htmlAssertion = tagInner.replaceAll("(?m)^\\s*\\*", "") String assertion = htmlAssertion // TODO improve on this [nbsp:' ', gt:'>', lt:'<', quot:'"', apos:"'", at:'@', ndash:'-', amp:'&'].each { key, value -> assertion = assertion.replaceAll("(?i)&$key;", value) } return assertion } private List getTestMethods(Map lineNumberToAssertions, String filename) { List testMethods = lineNumberToAssertions.collect { lineNumber, assertions -> Character differentiator = 'a' assertions.collect { assertion -> String suffix = (assertions.size() > 1 ? "$lineNumber$differentiator" : lineNumber) differentiator++ getTestMethodCodeForAssertion(suffix, assertion, basename(filename)) } }.flatten() return testMethods } private String basename(String fullPath) { def path = new File(fullPath) def fullName = path.name fullName.substring(0, fullName.lastIndexOf(".")) } private String getTestMethodCodeForAssertion(String suffix, String assertion, String basename) { return """ public void testAssertionFrom${basename}Line$suffix() { byte[] bytes = [ ${(assertion.getBytes("UTF-8") as List).join(", ")} ] as byte[] Eval.me(new String(bytes, "UTF-8")) } """ } private String getTestCode(String testName, List testMethods) { return """ class $testName extends junit.framework.TestCase { """+testMethods.join("\r\n")+""" } """ } private Class createClass(String testCode) { return new GroovyClassLoader().parseClass(testCode) } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy