Basic testing of IntrinsicHtml.

This commit is contained in:
JesseBrault0709 2024-05-10 18:08:02 +02:00
parent 3a171b8736
commit 6ee903bde0
4 changed files with 54 additions and 41 deletions

View File

@ -3,7 +3,6 @@ package groowt.view.web.lib
import groowt.view.View
import groowt.view.component.context.ComponentContext
import groowt.view.component.factory.ComponentFactory
import groowt.view.web.runtime.WebViewComponentChildCollector
class Echo extends DelegatingWebViewComponent {
@ -12,19 +11,11 @@ class Echo extends DelegatingWebViewComponent {
protected static class EchoFactory implements ComponentFactory<Echo> {
protected Echo doCreate() {
new Echo([:], [])
new Echo([:])
}
protected Echo doCreate(Map attr) {
new Echo(attr, [])
}
protected Echo doCreate(WebViewComponentChildCollector childCollector) {
new Echo([:], childCollector.children)
}
protected Echo doCreate(Map attr, WebViewComponentChildCollector childCollector) {
new Echo(attr, childCollector.children)
new Echo(attr)
}
@Override
@ -41,13 +32,17 @@ class Echo extends DelegatingWebViewComponent {
Map attr
Echo(Map attr, List children) {
Echo(Map attr) {
this.attr = attr
this.children = children
}
Object propertyMissing(String propertyName) {
attr[propertyName]
@Override
Object getProperty(String propertyName) {
try {
return super.getProperty(propertyName)
} catch (MissingPropertyException ignored) {
return attr[propertyName]
}
}
@Override

View File

@ -5,7 +5,6 @@ import groowt.view.component.ComponentRenderException
import groowt.view.component.context.ComponentContext
import groowt.view.component.context.ComponentScope.TypeAndFactory
import groowt.view.component.factory.ComponentFactory
import groowt.view.web.WebViewComponentChild
import groowt.view.web.util.WithHtml
class IntrinsicHtml extends DelegatingWebViewComponent implements WithHtml {
@ -26,27 +25,13 @@ class IntrinsicHtml extends DelegatingWebViewComponent implements WithHtml {
new IntrinsicHtml([:], typeName, typeName in voidElements)
}
IntrinsicHtml doCreate(String typeName, boolean selfClose) {
new IntrinsicHtml([:], typeName, selfClose)
}
IntrinsicHtml doCreate(String typeName, Map<String, Object> attr) {
new IntrinsicHtml(attr, typeName, typeName in voidElements)
}
IntrinsicHtml doCreate(String typeName, Map<String, Object> attr, boolean selfClose) {
new IntrinsicHtml(attr, typeName, selfClose)
}
IntrinsicHtml doCreate(String typeName, Map<String, Object> attr, List<WebViewComponentChild> children) {
def intrinsicHtml = new IntrinsicHtml(attr, typeName, typeName in voidElements)
intrinsicHtml.children = children
intrinsicHtml
}
@Override
IntrinsicHtml create(String typeName, ComponentContext componentContext, Object... args) {
return this.doCreate(typeName, componentContext, *args)
return this.doCreate(typeName, *args)
}
@Override
@ -58,18 +43,18 @@ class IntrinsicHtml extends DelegatingWebViewComponent implements WithHtml {
Map attr
String name
boolean selfClose
boolean isVoidElement
IntrinsicHtml(Map attr, String elementName, boolean selfClose) {
IntrinsicHtml(Map attr, String elementName, boolean isVoidElement) {
this.attr = attr
this.name = elementName
this.selfClose = selfClose
this.isVoidElement = isVoidElement
}
@Override
protected View getDelegate() {
if (this.selfClose && this.hasChildren()) {
throw new ComponentRenderException('Cannot have selfClose set to true and have children.')
if (this.isVoidElement && this.hasChildren()) {
throw new ComponentRenderException('A void html element cannot have children.')
}
return {
it << '<'
@ -78,9 +63,6 @@ class IntrinsicHtml extends DelegatingWebViewComponent implements WithHtml {
it << ' '
this.formatAttr(it)
}
if (this.selfClose) {
it << ' /'
}
it << '>'
if (this.hasChildren()) {
this.children.each {
@ -88,7 +70,7 @@ class IntrinsicHtml extends DelegatingWebViewComponent implements WithHtml {
renderer.call(it.child)
}
}
if (this.hasChildren() || !this.selfClose) {
if (!this.isVoidElement) {
it << '</'
it << this.name
it << '>'

View File

@ -1,5 +1,6 @@
package groowt.view.web.runtime;
import groovy.lang.Closure;
import groowt.view.component.ViewComponent;
import groowt.view.component.context.ComponentContext;
import groowt.view.component.runtime.ComponentWriter;
@ -19,12 +20,18 @@ public class DefaultWebViewComponentRenderContext extends DefaultRenderContext
if (args != null && args.length > 0) {
final Object last = args[args.length - 1];
if (last instanceof WebViewComponentChildCollectorClosure cl) {
final Object[] argsWithoutChildren = new Object[args.length - 1];
System.arraycopy(args, 0, argsWithoutChildren, 0, args.length - 1);
final WebViewComponent self = (WebViewComponent) super.create(resolved, argsWithoutChildren);
final var childCollector = new DefaultWebViewComponentChildCollector(
cl.getTemplate(),
this.getWriter()
);
args[args.length - 1] = childCollector;
cl.setDelegate(self);
cl.setResolveStrategy(Closure.DELEGATE_FIRST);
cl.call(childCollector);
self.setChildren(childCollector.getChildren());
return self;
}
}
return super.create(resolved, args);

View File

@ -0,0 +1,29 @@
package groowt.view.web.lib
import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.Test
class IntrinsicHtmlTests extends AbstractWebViewComponentTests {
@Test
void simplePElement() {
this.doTest('<p>Hello, World!</p>', '<p>Hello, World!</p>')
}
@Test
void h1Element() {
this.doTest('<h1>Hello!</h1>', '<h1>Hello!</h1>')
}
@Test
void attrTransferred() {
this.doTest('<h1 class="my-heading">Hello!</h1>', '<h1 class="my-heading">Hello!</h1>')
}
@Test
@Disabled('Until we figure out nested closure delegates')
void canUseEchoAttrProperty() {
this.doTest('<Echo greeting="Hello!"><p>$greeting</p></Echo>', '<p>Hello!</p>')
}
}