From 936587d0b58d41bda09d04ddeee762950b899a37 Mon Sep 17 00:00:00 2001 From: Jesse Brault Date: Sun, 12 Feb 2023 16:17:24 +0100 Subject: [PATCH] TagBuilder implemented and available in templates, parts, and specialPages. --- .../ssg/part/GspPartRenderer.groovy | 2 + .../specialpage/GspSpecialPageRenderer.groovy | 2 + .../ssg/tagbuilder/DynamicTagBuilder.groovy | 77 +++++++++++++++++++ .../ssg/tagbuilder/TagBuilder.groovy | 8 ++ .../ssg/template/GspTemplateRenderer.groovy | 2 + .../ssg/part/GspPartRendererTests.groovy | 8 ++ .../GspSpecialPageRendererTests.groovy | 8 ++ .../ssg/tagbuilder/TagBuilderTests.groovy | 54 +++++++++++++ .../template/GspTemplateRendererTests.groovy | 14 ++++ 9 files changed, 175 insertions(+) create mode 100644 lib/src/main/groovy/com/jessebrault/ssg/tagbuilder/DynamicTagBuilder.groovy create mode 100644 lib/src/main/groovy/com/jessebrault/ssg/tagbuilder/TagBuilder.groovy create mode 100644 lib/src/test/groovy/com/jessebrault/ssg/tagbuilder/TagBuilderTests.groovy diff --git a/lib/src/main/groovy/com/jessebrault/ssg/part/GspPartRenderer.groovy b/lib/src/main/groovy/com/jessebrault/ssg/part/GspPartRenderer.groovy index 84e7812..33ec3fb 100644 --- a/lib/src/main/groovy/com/jessebrault/ssg/part/GspPartRenderer.groovy +++ b/lib/src/main/groovy/com/jessebrault/ssg/part/GspPartRenderer.groovy @@ -1,6 +1,7 @@ package com.jessebrault.ssg.part import com.jessebrault.ssg.Diagnostic +import com.jessebrault.ssg.tagbuilder.DynamicTagBuilder import com.jessebrault.ssg.text.EmbeddableText import groovy.text.GStringTemplateEngine import groovy.text.TemplateEngine @@ -26,6 +27,7 @@ class GspPartRenderer implements PartRenderer { def result = engine.createTemplate(part.text).make([ binding: binding, globals: globals, + tagBuilder: new DynamicTagBuilder(), text: text ]) new Tuple2<>([], result.toString()) diff --git a/lib/src/main/groovy/com/jessebrault/ssg/specialpage/GspSpecialPageRenderer.groovy b/lib/src/main/groovy/com/jessebrault/ssg/specialpage/GspSpecialPageRenderer.groovy index cadb675..6810e24 100644 --- a/lib/src/main/groovy/com/jessebrault/ssg/specialpage/GspSpecialPageRenderer.groovy +++ b/lib/src/main/groovy/com/jessebrault/ssg/specialpage/GspSpecialPageRenderer.groovy @@ -3,6 +3,7 @@ package com.jessebrault.ssg.specialpage import com.jessebrault.ssg.Diagnostic import com.jessebrault.ssg.part.Part import com.jessebrault.ssg.part.EmbeddablePartsMap +import com.jessebrault.ssg.tagbuilder.DynamicTagBuilder import com.jessebrault.ssg.text.EmbeddableTextsCollection import com.jessebrault.ssg.text.Text import groovy.text.GStringTemplateEngine @@ -25,6 +26,7 @@ class GspSpecialPageRenderer implements SpecialPageRenderer { parts: new EmbeddablePartsMap(parts, globals, { Collection partDiagnostics -> diagnostics.addAll(partDiagnostics) }), + tagBuilder: new DynamicTagBuilder(), texts: new EmbeddableTextsCollection(texts, globals, { Collection textDiagnostics -> diagnostics.addAll(textDiagnostics) }) diff --git a/lib/src/main/groovy/com/jessebrault/ssg/tagbuilder/DynamicTagBuilder.groovy b/lib/src/main/groovy/com/jessebrault/ssg/tagbuilder/DynamicTagBuilder.groovy new file mode 100644 index 0000000..9acb4d0 --- /dev/null +++ b/lib/src/main/groovy/com/jessebrault/ssg/tagbuilder/DynamicTagBuilder.groovy @@ -0,0 +1,77 @@ +package com.jessebrault.ssg.tagbuilder + +import org.codehaus.groovy.runtime.InvokerHelper + +class DynamicTagBuilder implements TagBuilder { + + @Override + String create(String name) { + "<$name />" + } + + @Override + String create(String name, Map attributes) { + def formattedAttributes = attributes.collect { + if (it.value instanceof String) { + it.key + '="' + it.value + '"' + } else if (it.value instanceof Integer) { + it.key + '=' + it.value + } else if (it.value instanceof Boolean && it.value == true) { + it.key + } else { + it.key + '="' + it.value.toString() + '"' + } + }.join(' ') + "<$name $formattedAttributes />" + } + + @Override + String create(String name, String body) { + "<$name>$body" + } + + @Override + String create(String name, Map attributes, String body) { + def formattedAttributes = attributes.collect { + if (it.value instanceof String) { + it.key + '="' + it.value + '"' + } else if (it.value instanceof Integer) { + it.key + '=' + it.value + } else if (it.value instanceof Boolean && it.value == true) { + it.key + } else { + it.key + '="' + it.value.toString() + '"' + } + }.join(' ') + "<$name $formattedAttributes>$body" + } + + @Override + Object invokeMethod(String name, Object args) { + def argsList = InvokerHelper.asList(args) + return switch (argsList.size()) { + case 0 -> this.create(name) + case 1 -> { + def arg0 = argsList[0] + if (arg0 instanceof Map) { + this.create(name, arg0) + } else if (arg0 instanceof String) { + this.create(name, arg0) + } else { + throw new MissingMethodException(name, this.class, args, false) + } + } + case 2 -> { + def arg0 = argsList[0] + def arg1 = argsList[1] + if (arg0 instanceof Map && arg1 instanceof String) { + this.create(name, arg0, arg1) + } else { + throw new MissingMethodException(name, this.class, args, false) + } + } + default -> throw new MissingMethodException(name, this.class, args, false) + } + } + +} diff --git a/lib/src/main/groovy/com/jessebrault/ssg/tagbuilder/TagBuilder.groovy b/lib/src/main/groovy/com/jessebrault/ssg/tagbuilder/TagBuilder.groovy new file mode 100644 index 0000000..a92c64a --- /dev/null +++ b/lib/src/main/groovy/com/jessebrault/ssg/tagbuilder/TagBuilder.groovy @@ -0,0 +1,8 @@ +package com.jessebrault.ssg.tagbuilder + +interface TagBuilder { + String create(String name) + String create(String name, Map attributes) + String create(String name, String body) + String create(String name, Map attributes, String body) +} diff --git a/lib/src/main/groovy/com/jessebrault/ssg/template/GspTemplateRenderer.groovy b/lib/src/main/groovy/com/jessebrault/ssg/template/GspTemplateRenderer.groovy index fc91f9d..9ad0842 100644 --- a/lib/src/main/groovy/com/jessebrault/ssg/template/GspTemplateRenderer.groovy +++ b/lib/src/main/groovy/com/jessebrault/ssg/template/GspTemplateRenderer.groovy @@ -3,6 +3,7 @@ package com.jessebrault.ssg.template import com.jessebrault.ssg.Diagnostic import com.jessebrault.ssg.part.EmbeddablePartsMap import com.jessebrault.ssg.part.Part +import com.jessebrault.ssg.tagbuilder.DynamicTagBuilder import com.jessebrault.ssg.text.EmbeddableText import com.jessebrault.ssg.text.FrontMatter import com.jessebrault.ssg.text.Text @@ -35,6 +36,7 @@ class GspTemplateRenderer implements TemplateRenderer { frontMatter: frontMatter, globals: globals, parts: new EmbeddablePartsMap(parts, globals, onDiagnostics, embeddableText), + tagBuilder: new DynamicTagBuilder(), text: embeddableText ]) new Tuple2<>(diagnostics, result.toString()) diff --git a/lib/src/test/groovy/com/jessebrault/ssg/part/GspPartRendererTests.groovy b/lib/src/test/groovy/com/jessebrault/ssg/part/GspPartRendererTests.groovy index 724b329..b759e59 100644 --- a/lib/src/test/groovy/com/jessebrault/ssg/part/GspPartRendererTests.groovy +++ b/lib/src/test/groovy/com/jessebrault/ssg/part/GspPartRendererTests.groovy @@ -68,4 +68,12 @@ class GspPartRendererTests { assertEquals('Hello, World!', r.v2) } + @Test + void tagBuilderAvailable() { + def part = new Part('', null, '<%= tagBuilder.test() %>') + def r = this.renderer.render(part, [:], [:], null) + assertTrue(r.v1.isEmpty()) + assertEquals('', r.v2) + } + } diff --git a/lib/src/test/groovy/com/jessebrault/ssg/specialpage/GspSpecialPageRendererTests.groovy b/lib/src/test/groovy/com/jessebrault/ssg/specialpage/GspSpecialPageRendererTests.groovy index d949a37..df0a597 100644 --- a/lib/src/test/groovy/com/jessebrault/ssg/specialpage/GspSpecialPageRendererTests.groovy +++ b/lib/src/test/groovy/com/jessebrault/ssg/specialpage/GspSpecialPageRendererTests.groovy @@ -75,4 +75,12 @@ class GspSpecialPageRendererTests { assertEquals('

Hello, World!

\n', r.v2) } + @Test + void tagBuilderAvailable() { + def specialPage = new SpecialPage('<%= tagBuilder.test() %>', null, null) + def r = this.renderer.render(specialPage, [], [], [:]) + assertTrue(r.v1.isEmpty()) + assertEquals('', r.v2) + } + } diff --git a/lib/src/test/groovy/com/jessebrault/ssg/tagbuilder/TagBuilderTests.groovy b/lib/src/test/groovy/com/jessebrault/ssg/tagbuilder/TagBuilderTests.groovy new file mode 100644 index 0000000..e598822 --- /dev/null +++ b/lib/src/test/groovy/com/jessebrault/ssg/tagbuilder/TagBuilderTests.groovy @@ -0,0 +1,54 @@ +package com.jessebrault.ssg.tagbuilder + +import org.junit.jupiter.api.Test + +import static org.junit.jupiter.api.Assertions.assertEquals + +class TagBuilderTests { + + private final TagBuilder tagBuilder = new DynamicTagBuilder() + + @Test + void simple() { + assertEquals('', this.tagBuilder.create('test')) + } + + @Test + void withAttributes() { + assertEquals('', this.tagBuilder.create('test', [test: 'abc'])) + } + + @Test + void withBody() { + assertEquals('test', this.tagBuilder.create('test', 'test')) + } + + @Test + void withAttributesAndBody() { + assertEquals( + 'test', + this.tagBuilder.create('test', [test: 'abc'], 'test') + ) + } + + @Test + void dynamicSimple() { + assertEquals('', this.tagBuilder.test()) + } + + @Test + void dynamicWithAttributes() { + assertEquals('', this.tagBuilder.test([test: 'abc'])) + } + + @Test + void dynamicWithBody() { + assertEquals('test', this.tagBuilder.test('test')) + } + + @Test + void dynamicWithAttributesAndBody() { + assertEquals('test', this.tagBuilder.test([test: 'abc'], 'test')) + } + +} diff --git a/lib/src/test/groovy/com/jessebrault/ssg/template/GspTemplateRendererTests.groovy b/lib/src/test/groovy/com/jessebrault/ssg/template/GspTemplateRendererTests.groovy index d0c6470..50684a7 100644 --- a/lib/src/test/groovy/com/jessebrault/ssg/template/GspTemplateRendererTests.groovy +++ b/lib/src/test/groovy/com/jessebrault/ssg/template/GspTemplateRendererTests.groovy @@ -136,4 +136,18 @@ class GspTemplateRendererTests { assertEquals('Hello, World!', r.v2) } + @Test + void tagBuilderAvailable() { + def template = new Template('<%= tagBuilder.test() %>', null, null) + def r = this.renderer.render( + template, + new FrontMatter(null, [:]), + mockBlankText(), + [], + [:] + ) + assertTrue(r.v1.isEmpty()) + assertEquals('', r.v2) + } + }