7 Commits

Author SHA1 Message Date
David
023922a7db [maven-release-plugin] prepare release j2html-1.4.0 2019-01-24 14:42:55 +01:00
David
00c0461669 Auto format project 2019-01-24 14:24:21 +01:00
Robin Karlsson
cd6e0084ef Add Stream<DomContent> variants of each and with (#118) 2018-05-20 21:45:36 +02:00
Moandji Ezana
764b5d7759 Add TagCreator::each(Map, BiFunction) (#115) 2018-05-07 00:18:36 +02:00
David
d9c4963ff0 bump version 2018-05-01 12:29:02 +02:00
David
3ec15d28a5 woops 2018-05-01 12:28:13 +02:00
Moandji Ezana
f1680464d1 Do not indent textarea contents (#113)
* Do not indent textarea contents.

Fixes #102

* Restore import style

* Handle <pre> and TagCreator::each
2018-05-01 02:06:45 +02:00
23 changed files with 238 additions and 165 deletions

View File

@@ -13,12 +13,12 @@ The project webpage is [j2html.com](http://j2html.com).
<dependency>
<groupId>com.j2html</groupId>
<artifactId>j2html</artifactId>
<version>1.2.2</version>
<version>1.3.0</version>
</dependency>
```
### Or the gradle dependency
```
compile 'com.j2html:j2html:1.2.2'
compile 'com.j2html:j2html:1.3.0'
```
### Import TagCreator and start building HTML

View File

@@ -10,7 +10,7 @@
<groupId>com.j2html</groupId>
<artifactId>j2html</artifactId>
<version>1.3.0</version>
<version>1.4.0</version>
<name>j2html</name>
<description>Java to HTML builder with a fluent API</description>
@@ -64,12 +64,6 @@
<version>0.7.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>24.0-jre</version>
<scope>test</scope>
</dependency>
<!-- performance test dependencies -->
<dependency>

View File

@@ -10,29 +10,27 @@ import java.util.Collections;
public class Config {
private static String FOUR_SPACES = " ";
private Config() {
}
/**
* Change this to configure text-escaping
* For example, to disable escaping, do <code>{@code Config.textEscaper = text -> text;}</code>
*/
public static TextEscaper textEscaper = EscapeUtil::escape;
/**
* Change this to configure css-minification.
* The default minifier is https://github.com/barryvan/CSSMin
*/
public static Minifier cssMinifier = CSSMin::compressCss;
/**
* Change this to configure js-minification.
* The default minifier is a simple whitespace/newline stripper
*/
public static Minifier jsMinifier = JSMin::compressJs;
/**
* Change this to configure enable/disable closing empty tags
* The default is to NOT close them
*/
public static boolean closeEmptyTags = false;
private static String FOUR_SPACES = " ";
/**
* Change this to configure indentation when rendering formatted html
* The default is four spaces
@@ -40,10 +38,7 @@ public class Config {
public static Indenter indenter = (level, text) -> String.join("", Collections.nCopies(level, FOUR_SPACES)) + text;
/**
* Change this to configure enable/disable closing empty tags
* The default is to NOT close them
*/
public static boolean closeEmptyTags = false;
private Config() {
}
}

View File

@@ -14,9 +14,11 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class TagCreator {
@@ -82,6 +84,17 @@ public class TagCreator {
return DomContentJoiner.join(" ", true, stringOrDomObjects);
}
/**
* Creates a DomContent object containing HTML elements from a stream.
* Intended usage: {@literal each(numbers.stream().map(n -> li(n.toString())))}
*
* @param stream the stream of DomContent elements
* @return DomContent containing elements from the stream
*/
public static DomContent each(Stream<DomContent> stream) {
return new ContainerTag(null).with(stream);
}
/**
* Creates a DomContent object containing HTML using a mapping function on a collection
* Intended usage: {@literal each(numbers, n -> li(n.toString()))}
@@ -92,13 +105,27 @@ public class TagCreator {
* @return DomContent containing mapped data {@literal (ex. docs: [li(1), li(2), li(3)])}
*/
public static <T> DomContent each(Collection<T> collection, Function<? super T, DomContent> mapper) {
return tag(null).with(collection.stream().map(mapper).collect(Collectors.toList()));
return tag(null).with(collection.stream().map(mapper));
}
public static <I, T> DomContent each(final Map<I, T> map, final Function<Entry<I, T>, DomContent> mapper) {
return rawHtml(map.entrySet().stream().map(mapper.andThen(DomContent::render)).collect(Collectors.joining()));
}
/**
* Creates a DomContent object containing HTML using a mapping function on a map
* Intended usage: {@literal each(idsToNames, (id, name) -> li(id + " " + name))}
*
* @param <I> The type of the keys
* @param <T> The type of the values
* @param map the map to iterate over, ex: a map of values { 1: "Tom", 2: "Dick", 3: "Harry" }
* @param mapper the mapping function, ex: {@literal "(id, name) -> li(id + " " + name)"}
* @return DomContent containing mapped data {@literal (ex. docs: [li(1 Tom), li(2 Dick), li(3 Harry)])}
*/
public static <I, T> DomContent each(final Map<I, T> map, final BiFunction<I, T, DomContent> mapper) {
return rawHtml(map.entrySet().stream().map(entry -> mapper.andThen(DomContent::render).apply(entry.getKey(), entry.getValue())).collect(Collectors.joining()));
}
/**
* Filters a collection to a list, to be used with {@link j2html.TagCreator#each}
* Intended usage: {@literal each(filter(numbers, n -> n % 2 == 0), n -> li(n.toString()))}

View File

@@ -4,62 +4,6 @@ import j2html.tags.Tag;
public class Attr {
public static class ShortForm {
String id;
String classes;
private ShortForm(String id, String classes) {
this.id = id;
this.classes = classes;
}
boolean hasId() {
return id != null && !"".equals(id);
}
boolean hasClasses() {
return classes != null && !"".equals(classes);
}
}
public static ShortForm shortFormFromAttrsString(String attrs) {
if (!attrs.contains(".") && !attrs.contains(("#"))) {
throw new IllegalArgumentException("String must contain either id (#) or class (.)");
}
if (attrs.split("#").length > 2) {
throw new IllegalArgumentException("Only one id (#) allowed");
}
String id = "";
StringBuilder classes = new StringBuilder();
for (String attr : attrs.split("\\.")) {
if (attr.contains("#")) {
if (!attr.startsWith("#")) {
throw new IllegalArgumentException("# cannot be in the middle of string");
}
id = attr.replace("#", "");
} else {
classes.append(attr).append(" ");
}
}
return new ShortForm(id.trim(), classes.toString().trim());
}
public static <T extends Tag<T>> T addTo(T tag, ShortForm shortForm) {
if (shortForm.hasId() && shortForm.hasClasses()) {
return tag.withId(shortForm.id).withClass(shortForm.classes);
}
if (shortForm.hasId()) {
return tag.withId(shortForm.id);
}
if (shortForm.hasClasses()) {
return tag.withClass(shortForm.classes);
}
return tag;
}
private Attr() {
}
public static final String ACCEPT = "accept";
public static final String ACCEPT_CHARSET = "accept-charset";
public static final String ACCESSKEY = "accesskey";
@@ -170,5 +114,60 @@ public class Attr {
public static final String VALUE = "value";
public static final String WIDTH = "width";
public static final String WRAP = "wrap";
private Attr() {
}
public static ShortForm shortFormFromAttrsString(String attrs) {
if (!attrs.contains(".") && !attrs.contains(("#"))) {
throw new IllegalArgumentException("String must contain either id (#) or class (.)");
}
if (attrs.split("#").length > 2) {
throw new IllegalArgumentException("Only one id (#) allowed");
}
String id = "";
StringBuilder classes = new StringBuilder();
for (String attr : attrs.split("\\.")) {
if (attr.contains("#")) {
if (!attr.startsWith("#")) {
throw new IllegalArgumentException("# cannot be in the middle of string");
}
id = attr.replace("#", "");
} else {
classes.append(attr).append(" ");
}
}
return new ShortForm(id.trim(), classes.toString().trim());
}
public static <T extends Tag<T>> T addTo(T tag, ShortForm shortForm) {
if (shortForm.hasId() && shortForm.hasClasses()) {
return tag.withId(shortForm.id).withClass(shortForm.classes);
}
if (shortForm.hasId()) {
return tag.withId(shortForm.id);
}
if (shortForm.hasClasses()) {
return tag.withClass(shortForm.classes);
}
return tag;
}
public static class ShortForm {
String id;
String classes;
private ShortForm(String id, String classes) {
this.id = id;
this.classes = classes;
}
boolean hasId() {
return id != null && !"".equals(id);
}
boolean hasClasses() {
return classes != null && !"".equals(classes);
}
}
}

View File

@@ -4,6 +4,7 @@ import j2html.Config;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class ContainerTag extends Tag<ContainerTag> {
@@ -89,6 +90,18 @@ public class ContainerTag extends Tag<ContainerTag> {
}
/**
* Appends the DomContent-objects in the stream to the end of this element
*
* @param children Stream of DomContent-objects to be appended
* @return itself for easy chaining
*/
public ContainerTag with(Stream<DomContent> children) {
children.forEach(this::with);
return this;
}
/**
* Call with-method based on condition
* {@link #with(DomContent... children)}
@@ -137,27 +150,40 @@ public class ContainerTag extends Tag<ContainerTag> {
private String renderFormatted(int lvl) throws IOException {
StringBuilder sb = new StringBuilder();
renderOpenTag(sb, null);
if ("pre".equals(tagName) || "textarea".equals(tagName)) {
return this.render() + "\n";
if (hasTagName() && !isSelfFormattingTag()) {
sb.append("\n");
}
sb.append("\n");
if (!children.isEmpty()) {
for (DomContent c : children) {
lvl++;
if (c instanceof ContainerTag) {
sb.append(Config.indenter.indent(lvl, ((ContainerTag) c).renderFormatted(lvl)));
if (((ContainerTag) c).hasTagName()) {
sb.append(Config.indenter.indent(lvl, ((ContainerTag) c).renderFormatted(lvl)));
} else {
sb.append(Config.indenter.indent(lvl - 1, ((ContainerTag) c).renderFormatted(lvl - 1)));
}
} else if (isSelfFormattingTag()) {
sb.append(Config.indenter.indent(0, c.render()));
} else {
sb.append(Config.indenter.indent(lvl, c.render())).append("\n");
}
lvl--;
}
}
sb.append(Config.indenter.indent(lvl, ""));
if (!isSelfFormattingTag()) {
sb.append(Config.indenter.indent(lvl, ""));
}
renderCloseTag(sb);
sb.append("\n");
if (hasTagName()) {
sb.append("\n");
}
return sb.toString();
}
private boolean isSelfFormattingTag() {
return "textarea".equals(tagName) || "pre".equals(tagName);
}
@Override
public void renderModel(Appendable writer, Object model) throws IOException {
renderOpenTag(writer, model);

View File

@@ -10,8 +10,6 @@ import static j2html.TagCreator.style;
public class InlineStaticResource {
public enum TargetFormat {CSS_MIN, CSS, JS_MIN, JS}
public static ContainerTag get(String path, TargetFormat format) {
String fileString = getFileAsString(path);
switch (format) {
@@ -45,5 +43,7 @@ public class InlineStaticResource {
return s.hasNext() ? s.next() : "";
}
public enum TargetFormat {CSS_MIN, CSS, JS_MIN, JS}
}

View File

@@ -19,6 +19,10 @@ public abstract class Tag<T extends Tag<T>> extends DomContent {
return this.tagName;
}
protected boolean hasTagName() {
return tagName != null && !tagName.isEmpty();
}
String renderOpenTag() throws IOException {
StringBuilder stringBuilder = new StringBuilder();
renderOpenTag(stringBuilder, null);
@@ -32,7 +36,7 @@ public abstract class Tag<T extends Tag<T>> extends DomContent {
}
void renderOpenTag(Appendable writer, Object model) throws IOException {
if (tagName == null || tagName.equals("")) { // avoid <null> and <> tags
if (!hasTagName()) { // avoid <null> and <> tags
return;
}
writer.append("<").append(tagName);
@@ -43,7 +47,7 @@ public abstract class Tag<T extends Tag<T>> extends DomContent {
}
void renderCloseTag(Appendable writer) throws IOException {
if (tagName == null || tagName.equals("")) {
if (!hasTagName()) { // avoid <null> and <> tags
return;
}
writer.append("</");

View File

@@ -65,13 +65,11 @@ import java.util.regex.PatternSyntaxException;
public class CSSMin {
private CSSMin() {
}
private static final Logger LOG = Logger.getLogger(CSSMin.class.getName());
static boolean debugLogging = false;
private CSSMin() {
}
/**
* Minify supplied CSS.

View File

@@ -47,6 +47,16 @@ import java.io.PushbackInputStream;
public class JSMin {
private static final int EOF = -1;
private PushbackInputStream in;
private OutputStream out;
private int theA;
private int theB;
private JSMin(InputStream in, OutputStream out) {
this.in = new PushbackInputStream(in);
this.out = out;
}
/**
* Compress a JS-string
*
@@ -66,19 +76,6 @@ public class JSMin {
}
}
private static final int EOF = -1;
private PushbackInputStream in;
private OutputStream out;
private int theA;
private int theB;
private JSMin(InputStream in, OutputStream out) {
this.in = new PushbackInputStream(in);
this.out = out;
}
/**
* isAlphanum -- return true if the character is a letter, digit,
* underscore, dollar sign, or non-ASCII character.

View File

@@ -1 +1,2 @@
public class AnyContent{}
public class AnyContent {
}

View File

@@ -1,15 +1,5 @@
package j2html;
import static j2html.TagCreator.attrs;
import static j2html.TagCreator.body;
import static j2html.TagCreator.div;
import static j2html.TagCreator.h1;
import static j2html.TagCreator.h2;
import static j2html.TagCreator.head;
import static j2html.TagCreator.html;
import static j2html.TagCreator.p;
import static j2html.TagCreator.title;
import static org.junit.Assert.assertEquals;
import com.carrotsearch.junitbenchmarks.BenchmarkOptions;
import com.carrotsearch.junitbenchmarks.BenchmarkRule;
import com.carrotsearch.junitbenchmarks.Clock;
@@ -22,19 +12,28 @@ import j2html.tags.DomContent;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import static j2html.TagCreator.attrs;
import static j2html.TagCreator.body;
import static j2html.TagCreator.div;
import static j2html.TagCreator.h1;
import static j2html.TagCreator.h2;
import static j2html.TagCreator.head;
import static j2html.TagCreator.html;
import static j2html.TagCreator.p;
import static j2html.TagCreator.title;
import static org.junit.Assert.assertEquals;
@BenchmarkOptions(callgc = false, benchmarkRounds = 50000, warmupRounds = 200, concurrency = 2, clock = Clock.NANO_TIME)
public class RenderPerformanceTest {
String expected = "<html><head><title>Browsertitle</title></head><body><h1>Hello World!</h1><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><p>Hello World!</p></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div><h2 id=\"title\" class=\"visible-small\">Hello World!</h2><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><p>Hello World!</p></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div><h2>Hello World!</h2><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><p>Hello World!</p></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div><h2 id=\"title\" class=\"visible-small\">Hello World!</h2><div class=\"button\"><div class=\"button-text\">Action!</div></div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><p>Hello World!</p></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div><h2>Hello World!</h2><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><p>Hello World!</p></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div><h1>Hello World!</h1><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><p>Hello World!</p></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div><h2>Hello World!</h2><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><p>Hello World!</p></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div><h2>Hello World!</h2><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><p>Hello World!</p></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div><h2>Hello World!</h2><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><p>Hello World!</p></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div><h2>Hello World!</h2><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><p>Hello World!</p></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></body></html>";
@Rule
public TestRule benchmarkRun = new BenchmarkRule();
String expected = "<html><head><title>Browsertitle</title></head><body><h1>Hello World!</h1><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><p>Hello World!</p></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div><h2 id=\"title\" class=\"visible-small\">Hello World!</h2><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><p>Hello World!</p></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div><h2>Hello World!</h2><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><p>Hello World!</p></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div><h2 id=\"title\" class=\"visible-small\">Hello World!</h2><div class=\"button\"><div class=\"button-text\">Action!</div></div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><p>Hello World!</p></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div><h2>Hello World!</h2><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><p>Hello World!</p></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div><h1>Hello World!</h1><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><p>Hello World!</p></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div><h2>Hello World!</h2><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><p>Hello World!</p></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div><h2>Hello World!</h2><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><p>Hello World!</p></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div><h2>Hello World!</h2><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><p>Hello World!</p></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div><h2>Hello World!</h2><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><p>Hello World!</p></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></body></html>";
private DomContent template;
public RenderPerformanceTest() {
this.template =
// @formatter:off
// @formatter:off
html(
head(
title(new BrowserTitle())
@@ -68,7 +67,7 @@ public class RenderPerformanceTest {
private DomContent getDomContent(PageModel pageModel) throws Exception {
return
// @formatter:off
// @formatter:off
html(
head(
title(pageModel.getTitle())

View File

@@ -7,11 +7,11 @@ import java.util.stream.IntStream;
public class ComparisonData {
public static List<Integer> tableNumbers = IntStream.range(1, 51).boxed().collect(Collectors.toList());
public static List<Employee> fiveHundredEmployees() {
return IntStream.range(0, 500).mapToObj(i -> new Employee(i, "Some name", "Some title")).collect(Collectors.toList());
}
public static List<Integer> tableNumbers = IntStream.range(1, 51).boxed().collect(Collectors.toList());
}

View File

@@ -2,7 +2,11 @@ package j2html.comparison.j2html;
import j2html.comparison.ComparisonData;
import j2html.tags.ContainerTag;
import static j2html.TagCreator.*;
import static j2html.TagCreator.each;
import static j2html.TagCreator.table;
import static j2html.TagCreator.tbody;
import static j2html.TagCreator.td;
import static j2html.TagCreator.tr;
public class MultiplicationTable {

View File

@@ -1,10 +1,8 @@
package j2html.model;
import static j2html.TagCreator.div;
import java.io.IOException;
import j2html.tags.ContainerTag;
import java.io.IOException;
import static j2html.TagCreator.div;
public class Button extends Template<PageModel> {
@@ -37,4 +35,4 @@ class ButtonText extends Template<String> {
public void renderTemplate(Appendable writer, String model) throws IOException {
writer.append(model);
}
}
}

View File

@@ -6,7 +6,8 @@ public class ButtonModel {
public ButtonModel(String text) {
this.text = text;
}
public String getText() {
return text;
}
}
}

View File

@@ -1,8 +1,7 @@
package j2html.model;
import java.io.IOException;
import j2html.tags.DomContent;
import java.io.IOException;
public abstract class Template<T> extends DomContent {

View File

@@ -19,7 +19,7 @@ public class InlineStaticResourceTest {
String expectedJs = "<script>(function(){var test=5;var tast=10;var testTast=test+tast;console.log(testTast);})();</script>";
String expectedHtml = "<body>" + EOL + " Any content" + EOL + "</body>" + EOL;
String expectedEscapedHtml = "&lt;body&gt;" + EOL + " Any content" + EOL + "&lt;/body&gt;" + EOL;
String expectedAnyContent = "public class AnyContent{}" + EOL;
String expectedAnyContent = "public class AnyContent {" + EOL + "}" + EOL;
// classpath files
assertThat(styleWithInlineFile_min("/test.css").render(), is(expectedCss));

View File

@@ -1,6 +1,5 @@
package j2html.tags;
import com.google.common.collect.ImmutableList;
import org.junit.Test;
import static j2html.TagCreator.div;
import static j2html.TagCreator.each;
@@ -9,6 +8,7 @@ import static j2html.TagCreator.p;
import static j2html.TagCreator.pre;
import static j2html.TagCreator.textarea;
import static j2html.TagCreator.ul;
import static java.util.Arrays.asList;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
@@ -40,19 +40,17 @@ public class RenderFormattedTest {
@Test
public void testFormattedTags_each() throws Exception {
assertThat(ul(each(ImmutableList.of(1, 2, 3), i -> li("Number " + i))).renderFormatted(), is(
assertThat(ul(each(asList(1, 2, 3), i -> li("Number " + i))).renderFormatted(), is(
"<ul>\n" +
" \n" +
" <li>\n" +
" Number 1\n" +
" </li>\n" +
" <li>\n" +
" Number 2\n" +
" </li>\n" +
" <li>\n" +
" Number 3\n" +
" </li>\n" +
" \n" +
" <li>\n" +
" Number 1\n" +
" </li>\n" +
" <li>\n" +
" Number 2\n" +
" </li>\n" +
" <li>\n" +
" Number 3\n" +
" </li>\n" +
"</ul>\n"
));
}

View File

@@ -8,7 +8,6 @@ import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import static j2html.TagCreator.*;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -50,7 +49,7 @@ public class TagCreatorTest {
).render();
assertThat(actual, is(expected));
}
@Test
public void testIffOptional() {
String expected = "<div><p>Test</p><a href=\"#1\">Test</a></div>";
@@ -105,9 +104,19 @@ public class TagCreatorTest {
@Test
public void testEachWithMap() {
final String j2htmlMap = ul().with(
li("Begin list"),
each(employeeMap, entry -> li(entry.getKey() + "-" + entry.getValue().name))
final String j2htmlMap = ul().with(
li("Begin list"),
each(employeeMap, entry -> li(entry.getKey() + "-" + entry.getValue().name))
).render();
assertThat(j2htmlMap, is("<ul><li>Begin list</li><li>1-Name 1</li><li>2-Name 2</li><li>3-Name 3</li></ul>"));
}
@Test
public void testEachWithMapAndBiFunction() {
final String j2htmlMap = ul().with(
li("Begin list"),
each(employeeMap, (id, employee) -> li(id + "-" + employee.name))
).render();
assertThat(j2htmlMap, is("<ul><li>Begin list</li><li>1-Name 1</li><li>2-Name 2</li><li>3-Name 3</li></ul>"));
@@ -133,6 +142,16 @@ public class TagCreatorTest {
assertThat(j2htmlFilter.equals(javaFilter), is(true));
}
@Test
public void testEachWithStream() throws Exception {
final String j2htmlMap = ul().with(
li("Begin list"),
each(employeeMap.entrySet().stream().map(e -> li(e.getKey() + "-" + e.getValue().name)))
).render();
assertThat(j2htmlMap, is("<ul><li>Begin list</li><li>1-Name 1</li><li>2-Name 2</li><li>3-Name 3</li></ul>"));
}
@Test
public void testAllTags() throws Exception {

View File

@@ -1,5 +1,9 @@
package j2html.tags;
import j2html.Config;
import j2html.model.DynamicHrefAttribute;
import java.io.FileWriter;
import org.junit.Test;
import static j2html.TagCreator.body;
import static j2html.TagCreator.div;
import static j2html.TagCreator.footer;
@@ -13,9 +17,6 @@ import static j2html.TagCreator.p;
import static j2html.TagCreator.tag;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import j2html.Config;
import j2html.model.DynamicHrefAttribute;
import org.junit.Test;
public class TagTest {
@@ -55,6 +56,11 @@ public class TagTest {
Config.closeEmptyTags = false;
}
@Test
public void testFormattedTags() throws Exception { // better test in ComplexRenderTest.java
assertThat(div(p("Hello")).renderFormatted(), is("<div>\n <p>\n Hello\n </p>\n</div>\n"));
}
@Test
public void testEquals() throws Exception {
Tag tagOne = tag("p").withClass("class").withText("Test");
@@ -93,11 +99,18 @@ public class TagTest {
ContainerTag testTagWithAttrValueNull = new ContainerTag("a").attr(new DynamicHrefAttribute());
assertThat(testTagWithAttrValueNull.render(), is("<a href=\"/\"></a>"));
}
@Test
public void testDynamicAttributeReplacement() throws Exception {
ContainerTag testTagWithAttrValueNull = new ContainerTag("a").attr("href", "/link").attr(new DynamicHrefAttribute());
assertThat(testTagWithAttrValueNull.render(), is("<a href=\"/\"></a>"));
}
@Test
public void renderToFile() throws Exception {
FileWriter fileWriter = new FileWriter("file.txt");
div("Test").render(fileWriter);
fileWriter.close();
}
}

View File

@@ -1 +1,2 @@
public class AnyContent{}
public class AnyContent {
}

View File

@@ -13,16 +13,16 @@
#end
#@mainLayout()
<div>
<h1>Example content</h1>
#someMacro(1)
#someMacro(2)
#someMacro(3)
</div>
<div>
<h1>Example content</h1>
#someMacro(1)
#someMacro(2)
#someMacro(3)
</div>
#end
#macro(someMacro $callNumber)
<div>
Macro call $callNumber
</div>
<div>
Macro call $callNumber
</div>
#end