Author: cbrisson Date: Sat Oct 13 14:52:28 2018 New Revision: 1843764 URL: http://svn.apache.org/viewvc?rev=1843764&view=rev Log: [VELOCITY-898] WIP plus merge from trunk
Added: velocity/engine/branches/VELOCITY-898/velocity-engine-core/src/test/java/org/apache/velocity/test/AlternateValuesTestCase.java - copied, changed from r1843220, velocity/engine/branches/VELOCITY-898/velocity-engine-core/src/test/java/org/apache/velocity/test/BaseTestCase.java Modified: velocity/engine/branches/VELOCITY-898/ (props changed) velocity/engine/branches/VELOCITY-898/velocity-engine-core/pom.xml velocity/engine/branches/VELOCITY-898/velocity-engine-core/src/main/parser/Parser.jjt velocity/engine/branches/VELOCITY-898/velocity-engine-core/src/test/resources/templates/compare/diabolical.cmp velocity/engine/branches/VELOCITY-898/velocity-engine-core/src/test/resources/templates/diabolical.vm Propchange: velocity/engine/branches/VELOCITY-898/ ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Sat Oct 13 14:52:28 2018 @@ -1,2 +1,2 @@ /velocity/engine/branches/2.0_Exp:958513,991637-995742 -/velocity/engine/trunk:992133,1032159 +/velocity/engine/trunk:992133,1032159,1843220-1843763 Modified: velocity/engine/branches/VELOCITY-898/velocity-engine-core/pom.xml URL: http://svn.apache.org/viewvc/velocity/engine/branches/VELOCITY-898/velocity-engine-core/pom.xml?rev=1843764&r1=1843763&r2=1843764&view=diff ============================================================================== --- velocity/engine/branches/VELOCITY-898/velocity-engine-core/pom.xml (original) +++ velocity/engine/branches/VELOCITY-898/velocity-engine-core/pom.xml Sat Oct 13 14:52:28 2018 @@ -169,9 +169,9 @@ <buildParser>true</buildParser> <buildNodeFiles>${parser.nodefiles}</buildNodeFiles> <multi>true</multi> - <debugParser>false</debugParser> - <debugLookAhead>false</debugLookAhead> - <debugTokenManager>false</debugTokenManager> + <debugParser>true</debugParser> + <debugLookAhead>true</debugLookAhead> + <debugTokenManager>true</debugTokenManager> <jdkVersion>${maven.compiler.target}</jdkVersion> <nodeUsesParser>true</nodeUsesParser> <nodePackage>org.apache.velocity.runtime.parser.node</nodePackage> Modified: velocity/engine/branches/VELOCITY-898/velocity-engine-core/src/main/parser/Parser.jjt URL: http://svn.apache.org/viewvc/velocity/engine/branches/VELOCITY-898/velocity-engine-core/src/main/parser/Parser.jjt?rev=1843764&r1=1843763&r2=1843764&view=diff ============================================================================== --- velocity/engine/branches/VELOCITY-898/velocity-engine-core/src/main/parser/Parser.jjt (original) +++ velocity/engine/branches/VELOCITY-898/velocity-engine-core/src/main/parser/Parser.jjt Sat Oct 13 14:52:28 2018 @@ -466,7 +466,7 @@ TOKEN_MGR_DECLS: List stateStack = new ArrayList(50); /* More debug output */ - public boolean debugPrint = false; + public boolean debugPrint = true; private boolean inReference; private boolean inComment; @@ -675,7 +675,7 @@ TOKEN: } -<DIRECTIVE,REFMOD2> +<DIRECTIVE,REFMOD2,ALT_VAL> TOKEN: { <LBRACKET: "["> @@ -683,23 +683,42 @@ TOKEN: | <COMMA:","> } -<DIRECTIVE, REFMOD2> +<DIRECTIVE,REFMOD2,ALT_VAL> TOKEN: { <DOUBLEDOT : ".." > } -<DIRECTIVE, REFMOD2> +<DIRECTIVE, REFMOD2,ALT_VAL> TOKEN: { <COLON : ":" > } -<DIRECTIVE, REFMOD2> +<DIRECTIVE, REFMOD2, ALTVAL> TOKEN : { <LEFT_CURLEY : "{" > - | <RIGHT_CURLEY : "}" > + { + if (curLexState == ALT_VAL) + { + ++curlyLevel; + } + } + | + <RIGHT_CURLEY : "}" > + { + System.out.println("@@@@ RIGHT_CURLEY, curlyLevel was " + curlyLevel); + if (curLexState == ALT_VAL) + { + if (--curlyLevel == 0) + { + stateStackPop(); + System.out.println("@@@@ Poped state to " + lexStateNames[curLexState]); + } + + } + } } <DIRECTIVE,REFMODIFIER> @@ -788,7 +807,7 @@ TOKEN: * http://www.engr.mun.ca/~theo/JavaCC-FAQ/javacc-faq-ie.htm#tth_sEc3.12 * */ -<DEFAULT, PRE_REFERENCE, PRE_OLD_REFERENCE, REFERENCE, REFMODIFIER, REFMOD2> +<DEFAULT, PRE_REFERENCE, PRE_OLD_REFERENCE, REFERENCE, REFMODIFIER, REFMOD2, REFMOD3> TOKEN: { <SET_DIRECTIVE: ("#set" | "#{set}") (" "|"\t")* "("> @@ -1065,7 +1084,7 @@ MORE : * * ---------------------------------------------------------------------- */ -<DEFAULT,REFINDEX,REFMOD2,DIRECTIVE> +<DEFAULT,REFINDEX,REFMOD2,DIRECTIVE,ALT_VAL> TOKEN: { <WHITESPACE : ([" ","\t"])+> @@ -1074,8 +1093,6 @@ TOKEN: if ( debugPrint ) System.out.println(" NEWLINE :"); -// stateStackPop(); - if (inSet) inSet = false; } @@ -1348,8 +1365,10 @@ TOKEN : } | <RCURLY: "}"> { + System.out.println("@@@@ RCURLY, curlyLevel was " + curlyLevel); --curlyLevel; stateStackPop(); + System.out.println("@@@@ Poped state to " + lexStateNames[curLexState]); } } @@ -1955,7 +1974,7 @@ void Index() : {} void Reference() : {} { /* - * A reference is either $<FOO> or ${<FOO>} or ${<FOO>'|'<DEFAULT>) + * A reference is either $<FOO> or ${<FOO>} or ${<FOO>'|'<ALTERNATE_VALUE>) */ ( @@ -1964,11 +1983,11 @@ void Reference() : {} ) | ( - <LCURLY> + <LCURLY> { System.out.println("@@@@ INSIDE LCURLY"); } ( <IDENTIFIER> | <OLD_IDENTIFIER> ) (Index())* (LOOKAHEAD(2) <DOT> (LOOKAHEAD(3) Method() | Identifier() ) (Index())* )* - [ <PIPE> Expression() ] - <RCURLY> + [ <PIPE> { System.out.println("@@@@ FOUND PIPE"); } Expression() { System.out.println("@@@@ FOUND EXPRESSION"); } ] + ( <RCURLY> { System.out.println("@@@@ FOUND RCURLY"); } | <RIGHT_CURLEY> { System.out.println("@@@@ FOUND RIGHT_CURLEY"); } ) ) } @@ -2421,7 +2440,7 @@ void PrimaryExpression() #void : {} So, with a template : ------ - #set $foo="foo" + #set($foo="foo") #if($foo) \$foo = $foo #end Copied: velocity/engine/branches/VELOCITY-898/velocity-engine-core/src/test/java/org/apache/velocity/test/AlternateValuesTestCase.java (from r1843220, velocity/engine/branches/VELOCITY-898/velocity-engine-core/src/test/java/org/apache/velocity/test/BaseTestCase.java) URL: http://svn.apache.org/viewvc/velocity/engine/branches/VELOCITY-898/velocity-engine-core/src/test/java/org/apache/velocity/test/AlternateValuesTestCase.java?p2=velocity/engine/branches/VELOCITY-898/velocity-engine-core/src/test/java/org/apache/velocity/test/AlternateValuesTestCase.java&p1=velocity/engine/branches/VELOCITY-898/velocity-engine-core/src/test/java/org/apache/velocity/test/BaseTestCase.java&r1=1843220&r2=1843764&rev=1843764&view=diff ============================================================================== --- velocity/engine/branches/VELOCITY-898/velocity-engine-core/src/test/java/org/apache/velocity/test/BaseTestCase.java (original) +++ velocity/engine/branches/VELOCITY-898/velocity-engine-core/src/test/java/org/apache/velocity/test/AlternateValuesTestCase.java Sat Oct 13 14:52:28 2018 @@ -29,7 +29,6 @@ import org.apache.velocity.runtime.resou import org.apache.velocity.test.misc.TestLogger; import java.io.File; -import java.io.FileReader; import java.io.IOException; import java.io.StringWriter; import java.nio.charset.StandardCharsets; @@ -45,470 +44,17 @@ import java.util.Locale; * @author Nathan Bubna * @version $Id$ */ -public abstract class BaseTestCase extends TestCase implements TemplateTestBase +public class AlternateValuesTestCase extends BaseTestCase { - protected VelocityEngine engine; - protected VelocityContext context; - protected boolean DEBUG = false; - protected TestLogger log; - protected String stringRepoName = "string.repo"; - - public BaseTestCase(String name) + public AlternateValuesTestCase(String name) { super(name); - - // if we're just running one case, then have DEBUG - // automatically set to true - String test = System.getProperty("test"); - if (test != null) - { - DEBUG = test.equals(getClass().getSimpleName()); - } - } - - protected VelocityEngine createEngine() - { - VelocityEngine ret = new VelocityEngine(); - ret.setProperty(RuntimeConstants.RUNTIME_LOG_INSTANCE, log); - - // use string resource loader by default, instead of file - ret.setProperty(RuntimeConstants.RESOURCE_LOADER, "file,string"); - ret.addProperty("string.resource.loader.class", StringResourceLoader.class.getName()); - ret.addProperty("string.resource.loader.repository.name", stringRepoName); - ret.addProperty("string.resource.loader.repository.static", "false"); - - setUpEngine(ret); - return ret; - } - - protected void setUp() throws Exception - { - //by default, make the engine's log output go to the test-report - log = new TestLogger(false, false); - engine = createEngine(); - context = new VelocityContext(); - setUpContext(context); - } - - protected void setUpEngine(VelocityEngine engine) - { - // extension hook - } - - protected void setUpContext(VelocityContext context) - { - // extension hook - } - - protected StringResourceRepository getStringRepository() - { - StringResourceRepository repo = - (StringResourceRepository)engine.getApplicationAttribute(stringRepoName); - if (repo == null) - { - engine.init(); - repo = - (StringResourceRepository)engine.getApplicationAttribute(stringRepoName); - } - return repo; - } - - protected void addTemplate(String name, String template) - { - info("Template '"+name+"': "+template); - getStringRepository().putStringResource(name, template); - } - - protected void removeTemplate(String name) - { - info("Removed: '"+name+"'"); - getStringRepository().removeStringResource(name); } - public void tearDown() + public void testDefault() { - engine = null; - context = null; + assertEvalEquals("<foo>", "<${foo|$foo}>"); + assertEvalEquals("bar", "#set($bar='bar')${foo|$bar}"); } - protected void info(String msg) - { - info(msg, null); - } - - protected void info(String msg, Throwable t) - { - if (DEBUG) - { - try - { - if (engine == null) - { - Velocity.getLog().info(msg, t); - } - else - { - engine.getLog().info(msg, t); - } - } - catch (Throwable t2) - { - System.out.println("Failed to log: "+msg+(t!=null?" - "+t: "")); - System.out.println("Cause: "+t2); - t2.printStackTrace(); - } - } - } - - /** - * Compare an expected string with the given loaded template - */ - protected void assertTmplEquals(String expected, String template) - { - info("Expected: " + expected + " from '" + template + "'"); - - StringWriter writer = new StringWriter(); - try - { - engine.mergeTemplate(template, "utf-8", context, writer); - } - catch (RuntimeException re) - { - info("RuntimeException!", re); - throw re; - } - catch (Exception e) - { - info("Exception!", e); - throw new RuntimeException(e); - } - - info("Result: " + writer.toString()); - assertEquals(expected, writer.toString()); - } - - /** - * Ensure that a context value is as expected. - */ - protected void assertContextValue(String key, Object expected) - { - info("Expected value of '"+key+"': "+expected); - Object value = context.get(key); - info("Result: "+value); - assertEquals(expected, value); - } - - /** - * Ensure that a template renders as expected. - */ - protected void assertEvalEquals(String expected, String template) - { - info("Expectation: "+expected); - assertEquals(expected, evaluate(template)); - } - - /** - * Ensure that the given string renders as itself when evaluated. - */ - protected void assertSchmoo(String templateIsExpected) - { - assertEvalEquals(templateIsExpected, templateIsExpected); - } - - /** - * Ensure that an exception occurs when the string is evaluated. - */ - protected Exception assertEvalException(String evil) - { - return assertEvalException(evil, null); - } - - /** - * Ensure that a specified type of exception occurs when evaluating the string. - */ - protected Exception assertEvalException(String evil, Class exceptionType) - { - try - { - if (!DEBUG) - { - log.off(); - } - if (exceptionType != null) - { - info("Expectation: "+exceptionType.getName()); - } - else - { - info("Expectation: "+Exception.class.getName()); - } - evaluate(evil); - String msg = "Template '"+evil+"' should have thrown an exception."; - info("Fail: "+msg); - fail(msg); - } - catch (Exception e) - { - if (exceptionType != null && !exceptionType.isAssignableFrom(e.getClass())) - { - String msg = "Was expecting template '"+evil+"' to throw "+exceptionType+" not "+e; - info("Fail: "+msg); - fail(msg); - } - return e; - } - finally - { - if (!DEBUG) - { - log.on(); - } - } - return null; - } - - /** - * Ensure that the error message of the expected exception has the proper location info. - */ - protected Exception assertEvalExceptionAt(String evil, String template, - int line, int col) - { - String loc = template+"[line "+line+", column "+col+"]"; - info("Expectation: Exception at "+loc); - Exception e = assertEvalException(evil); - - info("Result: "+e.getClass().getName()+" - "+e.getMessage()); - if (e.getMessage().indexOf(loc) < 1) - { - fail("Was expecting exception at "+loc+" instead of "+e.getMessage()); - } - return e; - } - - /** - * Only ensure that the error message of the expected exception - * has the proper line and column info. - */ - protected Exception assertEvalExceptionAt(String evil, int line, int col) - { - return assertEvalExceptionAt(evil, "", line, col); - } - - /** - * Evaluate the specified String as a template and return the result as a String. - */ - protected String evaluate(String template) - { - StringWriter writer = new StringWriter(); - try - { - info("Template: "+template); - - // use template as its own name, since our templates are short - // unless it's not that short, then shorten it... - String name = (template.length() <= 15) ? template : template.substring(0,15); - engine.evaluate(context, writer, name, template); - - String result = writer.toString(); - info("Result: "+result); - return result; - } - catch (RuntimeException re) - { - info("RuntimeException!", re); - throw re; - } - catch (Exception e) - { - info("Exception!", e); - throw new RuntimeException(e); - } - } - - /** - * Concatenates the file name parts together appropriately. - * - * @return The full path to the file. - */ - protected String getFileName(final String dir, final String base, final String ext) - { - return getFileName(dir, base, ext, false); - } - - protected String getFileName(final String dir, final String base, final String ext, final boolean mustExist) - { - StringBuilder buf = new StringBuilder(); - try - { - File baseFile = new File(base); - if (dir != null) - { - if (!baseFile.isAbsolute()) - { - baseFile = new File(dir, base); - } - - buf.append(baseFile.getCanonicalPath()); - } - else - { - buf.append(baseFile.getPath()); - } - - if (org.apache.commons.lang3.StringUtils.isNotEmpty(ext)) - { - buf.append('.').append(ext); - } - - if (mustExist) - { - File testFile = new File(buf.toString()); - - if (!testFile.exists()) - { - String msg = "getFileName() result " + testFile.getPath() + " does not exist!"; - info(msg); - fail(msg); - } - - if (!testFile.isFile()) - { - String msg = "getFileName() result " + testFile.getPath() + " is not a file!"; - info(msg); - fail(msg); - } - } - } - catch (IOException e) - { - fail("IO Exception while running getFileName(" + dir + ", " + base + ", "+ ext + ", " + mustExist + "): " + e.getMessage()); - } - - return buf.toString(); - } - - /** - * Assures that the results directory exists. If the results directory - * cannot be created, fails the test. - */ - protected void assureResultsDirectoryExists(String resultsDirectory) - { - File dir = new File(resultsDirectory); - if (!dir.exists()) - { - info("Template results directory ("+resultsDirectory+") does not exist"); - if (dir.mkdirs()) - { - info("Created template results directory"); - if (DEBUG) - { - info("Created template results directory: "+resultsDirectory); - } - } - else - { - String errMsg = "Unable to create '"+resultsDirectory+"'"; - info(errMsg); - fail(errMsg); - } - } - } - - - /** - * Normalizes lines to account for platform differences. Macs use - * a single \r, DOS derived operating systems use \r\n, and Unix - * uses \n. Replace each with a single \n. - * - * @return source with all line terminations changed to Unix style - */ - protected String normalizeNewlines (String source) - { - return source.replaceAll("\r\n?", "\n"); - } - - /** - * Returns whether the processed template matches the - * content of the provided comparison file. - * - * @return Whether the output matches the contents - * of the comparison file. - * - * @exception Exception Test failure condition. - */ - protected boolean isMatch (String resultsDir, - String compareDir, - String baseFileName, - String resultExt, - String compareExt) throws Exception - { - if (DEBUG) - { - info("Result: "+resultsDir+'/'+baseFileName+'.'+resultExt); - } - String result = getFileContents(resultsDir, baseFileName, resultExt); - return isMatch(result,compareDir,baseFileName,compareExt); - } - - - protected String getFileContents(String dir, String baseFileName, String ext) - { - String fileName = getFileName(dir, baseFileName, ext, true); - return getFileContents(fileName); - } - - protected String getFileContents(String file) - { - String contents = null; - - try - { - contents = new String(Files.readAllBytes(Paths.get(file)), StandardCharsets.UTF_8); - } - catch (Exception e) - { - e.printStackTrace(); - } - return contents; - } - - /** - * Returns whether the processed template matches the - * content of the provided comparison file. - * - * @return Whether the output matches the contents - * of the comparison file. - * - * @exception Exception Test failure condition. - */ - protected boolean isMatch (String result, - String compareDir, - String baseFileName, - String compareExt) throws Exception - { - String compare = getFileContents(compareDir, baseFileName, compareExt); - - // normalize each wrt newline - result = normalizeNewlines(result); - compare = normalizeNewlines(compare); - if (DEBUG) - { - info("Expection: "+compareDir+'/'+baseFileName+'.'+compareExt); - } - return result.equals(compare); - } - - /** - * Turns a base file name into a test case name. - * - * @param s The base file name. - * @return The test case name. - */ - protected static String getTestCaseName(String s) - { - StringBuilder name = new StringBuilder(); - name.append(Character.toTitleCase(s.charAt(0))); - name.append(s.substring(1, s.length()).toLowerCase(Locale.ROOT)); - return name.toString(); - } } Modified: velocity/engine/branches/VELOCITY-898/velocity-engine-core/src/test/resources/templates/compare/diabolical.cmp URL: http://svn.apache.org/viewvc/velocity/engine/branches/VELOCITY-898/velocity-engine-core/src/test/resources/templates/compare/diabolical.cmp?rev=1843764&r1=1843763&r2=1843764&view=diff ============================================================================== --- velocity/engine/branches/VELOCITY-898/velocity-engine-core/src/test/resources/templates/compare/diabolical.cmp (original) +++ velocity/engine/branches/VELOCITY-898/velocity-engine-core/src/test/resources/templates/compare/diabolical.cmp Sat Oct 13 14:52:28 2018 @@ -48,3 +48,6 @@ $nullToString $nullToString.toString() + +$ +$fooo$fooo.$fooo.bar$fooo.bar($fooo.bar() \ No newline at end of file Modified: velocity/engine/branches/VELOCITY-898/velocity-engine-core/src/test/resources/templates/diabolical.vm URL: http://svn.apache.org/viewvc/velocity/engine/branches/VELOCITY-898/velocity-engine-core/src/test/resources/templates/diabolical.vm?rev=1843764&r1=1843763&r2=1843764&view=diff ============================================================================== --- velocity/engine/branches/VELOCITY-898/velocity-engine-core/src/test/resources/templates/diabolical.vm (original) +++ velocity/engine/branches/VELOCITY-898/velocity-engine-core/src/test/resources/templates/diabolical.vm Sat Oct 13 14:52:28 2018 @@ -65,3 +65,10 @@ $nullToString $nullToString.toString() $!nullToString $!nullToString.toString() + +$#set($foo = $bar) +$fooo#set($foo = $bar) +$fooo.#set($foo = $bar) +$fooo.bar#set($foo = $bar) +$fooo.bar(#set($foo = $bar) +$fooo.bar()#set($foo = $bar)