Skip to content

Commit

Permalink
Whitespace Control with New Line Trimming Disabled Tests (#477)
Browse files Browse the repository at this point in the history
* #422: Added inline verbatim description to Verbatim tag documentation

* Added tests for whitespace control for templates when New Line Trimming is enabled. Also added assertj and commons-io Maven dependencies for use in the tests. Commons IO is used to compare template output to expected output that is loaded from a file. Loading the expected template output from a file is useful for testing multiline template output, which is necessary to test various scenarios. These are a form of Integration Test rather than Unit Tests and so it is practical and reasonable to verify the template output in this way.

* Added javadoc to describe the purpose of several existing tests and changed the test method names in some cases to make the purpose of each test method more clear.

* Added a 3rd elseif in the template for the For Loop with Nested If Statement Thatis Skipped test

* Added tests with 2 ifelse in a nested if and also 3 ifelse in a nested if.

* Added test of Nested If with One ifelse statement

* Improved and added additional whitespace control tests.
  • Loading branch information
nward1234 authored and ebussieres committed Oct 19, 2019
1 parent a860905 commit 40b722d
Show file tree
Hide file tree
Showing 18 changed files with 558 additions and 18 deletions.
14 changes: 14 additions & 0 deletions pebble/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,20 @@
</exclusion>
</exclusions>
</dependency>
<!-- https://mvnrepository.com/artifact/org.assertj/assertj-core -->
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.13.2</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,13 @@ public void testPrintForceToTrue() throws PebbleException, IOException {
assertEquals("val1val2", writer.toString());
}

/**
* Given that Newline Trimming is disabled,
* a template that contains one newline character with text on each line
* should output one newline character.
*/
@Test
public void testPrintSetToFalse() throws PebbleException, IOException {
public void testNewLineIncludedWhen_NewLineTrimmingIsFalse() throws PebbleException, IOException {

PebbleEngine pebble = new PebbleEngine.Builder().loader(new StringLoader())
.newLineTrimming(false)
Expand Down Expand Up @@ -100,8 +105,13 @@ public void testPrintDefaultTwoNewlines() throws PebbleException, IOException {
assertEquals("val1\nval2", writer.toString());
}

/**
* Given that Newline Trimming is disabled,
* a template that contains one or more consecutive newline characters
* should output one newline character.
*/
@Test
public void testPrintSetToFalseTwoNewlines() throws PebbleException, IOException {
public void testOneNewLineWhen_NewLineTrimmingFalseAndConsecutiveNewLinesInTemplate() throws PebbleException, IOException {

PebbleEngine pebble = new PebbleEngine.Builder().loader(new StringLoader())
.newLineTrimming(false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,38 +10,68 @@

import static org.junit.Assert.assertEquals;

import com.mitchellbosecke.pebble.error.PebbleException;
import com.mitchellbosecke.pebble.loader.StringLoader;
import com.mitchellbosecke.pebble.template.PebbleTemplate;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;

import org.junit.Test;

import com.mitchellbosecke.pebble.error.PebbleException;
import com.mitchellbosecke.pebble.loader.StringLoader;
import com.mitchellbosecke.pebble.template.PebbleTemplate;

public class WhitespaceControlTest {

/**
* A windows newline character (i.e. \n\r) in a template should be recognized
* and output as as a Windows newline character. The Windows newline character
* should not be converted to a Unix newline character (i.e. \n).
*
* @throws PebbleException
* @throws IOException
*/
@Test
public void testStandardizationOfNewlineCharacters() throws PebbleException, IOException {
public void testWindowsNewlineCharacter() throws PebbleException, IOException {
PebbleEngine pebble = new PebbleEngine.Builder().loader(new StringLoader())
.strictVariables(true).build();

// windows
PebbleTemplate windowsTemplate = pebble.getTemplate("\r\n");
Writer windowsWriter = new StringWriter();
windowsTemplate.evaluate(windowsWriter);
assertEquals("\r\n", windowsWriter.toString());
}

/**
* A Unix newline character (i.e. \n\r) in a template should be recognized
* and output as as a Unix newline character. The Unix newline character
* should not be converted to a Windows newline character (i.e. \r\n).
*
* @throws PebbleException
* @throws IOException
*/
@Test
public void testUnixNewlineCharacter() throws PebbleException, IOException {
PebbleEngine pebble = new PebbleEngine.Builder().loader(new StringLoader())
.strictVariables(true).build();

// unix
PebbleTemplate unixTemplate = pebble.getTemplate("\n");
Writer unixWriter = new StringWriter();
unixTemplate.evaluate(unixWriter);
assertEquals("\n", unixWriter.toString());
}

/**
* A leading Whitespace Control Modifier in an expression delimiter (i.e. Pebble variable reference)
* should remove whitespace before the variable reference on the same line up to any
* surrounding text, i.e. a print delimiter.
*
* @throws PebbleException
* @throws IOException
*/
@Test
public void testLeadingWhitespaceTrimWithPrintDelimiter() throws PebbleException, IOException {
public void testLeadingWhitespaceControlModifier() throws PebbleException, IOException {
PebbleEngine pebble = new PebbleEngine.Builder().loader(new StringLoader())
.strictVariables(true).build();

Expand All @@ -54,36 +84,60 @@ public void testLeadingWhitespaceTrimWithPrintDelimiter() throws PebbleException
assertEquals("<li>bar</li>", writer.toString());
}

/**
* A trailing Whitespace Control Modifier in an expression delimiter (i.e. Pebble variable reference)
* should remove whitespace after the variable reference on the same line up to any
* surrounding text.
*
* @throws PebbleException
* @throws IOException
*/
@Test
public void testLeadingWhitespaceTrimWithoutOutsideText() throws PebbleException, IOException {
public void testTrailingWhitespaceControlModifier() throws PebbleException, IOException {
PebbleEngine pebble = new PebbleEngine.Builder().loader(new StringLoader())
.strictVariables(true).build();

PebbleTemplate template = pebble.getTemplate("{{- foo -}}");
PebbleTemplate template = pebble.getTemplate("<li>{{ foo -}} </li>");
Writer writer = new StringWriter();

Map<String, Object> context = new HashMap<>();
context.put("foo", "bar");
template.evaluate(writer, context);
assertEquals("bar", writer.toString());
assertEquals("<li>bar</li>", writer.toString());
}


/**
* A Whitespace Control Modifier in an expression delimiter (i.e. Pebble variable reference)
* should not have any effect if there is no whitespace immediately before or after the
* variable reference.
*
* @throws PebbleException
* @throws IOException
*/
@Test
public void testTrailingWhitespaceTrimWithPrintDelimiter() throws PebbleException, IOException {
public void testLeadingWhitespaceTrimWithoutOutsideText() throws PebbleException, IOException {
PebbleEngine pebble = new PebbleEngine.Builder().loader(new StringLoader())
.strictVariables(true).build();

PebbleTemplate template = pebble.getTemplate("<li>{{ foo -}} </li>");
PebbleTemplate template = pebble.getTemplate("{{- foo -}}");
Writer writer = new StringWriter();

Map<String, Object> context = new HashMap<>();
context.put("foo", "bar");
template.evaluate(writer, context);
assertEquals("<li>bar</li>", writer.toString());
assertEquals("bar", writer.toString());
}

/**
* A leading and trailing Whitespace Control Modifiers in an expression delimiter
* (i.e. Pebble variable reference) should remove whitespace before and after
* the variable reference on the same line up to any surrounding text.
*
* @throws PebbleException
* @throws IOException
*/
@Test
public void testWhitespaceTrimInPresenceOfMultipleTags() throws PebbleException, IOException {
public void testLeadingAndTrailingWhitespaceControlModifier() throws PebbleException, IOException {
PebbleEngine pebble = new PebbleEngine.Builder().loader(new StringLoader())
.strictVariables(true).build();

Expand All @@ -97,8 +151,15 @@ public void testWhitespaceTrimInPresenceOfMultipleTags() throws PebbleException,
assertEquals("bar <li>bar</li> bar", writer.toString());
}

/**
* Newline characters immediately before or after a Whitespace Control Modifier
* should be removed.
*
* @throws PebbleException
* @throws IOException
*/
@Test
public void testWhitespaceTrimRemovesNewlines() throws PebbleException, IOException {
public void testWhitespaceControlModifierRemovesNewlines() throws PebbleException, IOException {
PebbleEngine pebble = new PebbleEngine.Builder().loader(new StringLoader())
.strictVariables(true).build();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
package com.mitchellbosecke.pebble.template.tests;

import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.mitchellbosecke.pebble.PebbleEngine;
import com.mitchellbosecke.pebble.loader.StringLoader;
import com.mitchellbosecke.pebble.template.PebbleTemplate;

/**
* Used by Pebble Template Tests to simply the test code and therefore
* make it easier to understand what is tested by each test.
*
* A separate instance of this class should be instantiated for each
* template test, i.e. for each instance of a template.
*
* @author nathanward
*/
public class PebbleTestContext {

private final Logger logger = LoggerFactory.getLogger(PebbleTestContext.class);

/**
* The path relative to the project root directory where template files and
* expected output files are stored for test purposes.
*/
private String testFileBasePath = "src/test/resources/template-tests";

/**
* The Pebble template context to be used as input for a Pebble Template.
*/
private Map<String, Object> templateContext = null;

/**
* Whether or not the Pebble Engine instantiated will
* enable New Line Trimming on the Builder when this class instantiates
* a Pebble Engine instance. Defaults to <code>true</code>.
*/
private boolean newLineTrimming = true;

/**
* Initialize the Pebble Template Context.
*/
public PebbleTestContext() {
this.templateContext = new HashMap<String, Object>();
}

public void setNewLineTrimming(boolean b) {
this.newLineTrimming = b;
}

/**
* Put an object into the Pebble template context to be used as input for
* when the template is executed. One or more items can be put into the template
* context.
*
* @param name Template input/parameter name (i.e. key) for use within the template
* @param value The object that will be referred to by the given name in the template
*/
public void setTemplateInput(String name, Object value) {
this.templateContext.put(name, value);
}

/**
* Load the specified template file and execute the template using a
* Pebble Engine using the default Builder (classpath and file builder).
*
* @param templateFilename The template filename relative to the Test File Base Path
*
* @return The output of the template as a string.
*
* @throws IOException Thrown if the template file is not found.
*/
public String executeTemplateFromFile(String templateFilename) throws IOException {
PebbleEngine pebbleEngine = new PebbleEngine.Builder()
.newLineTrimming(this.newLineTrimming).strictVariables(true).build();
return this.executeTemplateFromFile(templateFilename, pebbleEngine);
}

/**
* Execute a template given a template file and a Pebble Engine instance.
*
* @param templateFilename The template filename relative to the Test File Base Path
* @param pebbleEngine
* @return
* @throws IOException
*/
public String executeTemplateFromFile(String templateFilename, PebbleEngine pebbleEngine) throws IOException {
Path path = Paths.get(this.testFileBasePath, templateFilename);
logger.debug("Executing template file: {}", path.toString());
return this.executeTemplate(path.toAbsolutePath().toString(), pebbleEngine);
}

/**
* Load the specified template file and execute the template using a
* Pebble Engine using the default Builder (classpath and file builder).
*
* @param templateString The template content as a string
*
* @return The output of the template as a string.
*
* @throws IOException Thrown if the template file is not found.
*/
public String executeTemplateFromString(String templateString) throws IOException {
PebbleEngine pebbleEngine = new PebbleEngine.Builder().loader(new StringLoader())
.newLineTrimming(this.newLineTrimming).build();
return this.executeTemplate(templateString, pebbleEngine);
}

/**
* Load the specified template file and execute the template using the template input
* that has previously been specified using the setTemplateInput() method.
*
* @param templateFilename The template filename relative to the Test File Base Path
* @param pebbleEngine The Pebble Engine to be used to execute the template
* @return The output of the template as a string.
*
* @throws IOException Thrown if the template file is not found.
*/
public String executeTemplate(String templateName, PebbleEngine pebbleEngine) throws IOException {
PebbleTemplate template = pebbleEngine.getTemplate(templateName);
Writer writer = new StringWriter();
template.evaluate(writer, this.templateContext);
String templateOutput = writer.toString();
logger.debug("Template Output: {}", templateOutput);
return templateOutput;
}

/**
* Get the Expected Output content for the given filename so that the
* base path to the expected template output file does not have to be
* specified in the actual test code.
*
* @param filename The name of the file that contains the expected template output.
* @return The content of the expected template output file as a string.
* @throws IOException Thrown if the file by the given name is not found.
*/
public String getExpectedOutput(String filename) throws IOException {
Path path = Paths.get(this.testFileBasePath, filename);
logger.debug("Expected template output file: {}", path.toAbsolutePath());
String expectedOutput = FileUtils.readFileToString(path.toFile(), "UTF-8");
return expectedOutput;
}

}
Loading

0 comments on commit 40b722d

Please sign in to comment.