Parts now have access to all parts via a EmbeddablePartsMap.

This commit is contained in:
Jesse Brault 2023-02-13 15:08:58 +01:00
parent 25f4b3657d
commit 0e49414db7
6 changed files with 65 additions and 10 deletions

View File

@ -18,12 +18,15 @@ class EmbeddablePart {
@Nullable
private final EmbeddableText text
private final Collection<Part> allParts
String render(Map binding = [:]) {
def result = part.type.renderer.render(
this.part,
binding,
this.globals,
this.text
this.text,
this.allParts
)
if (result.v1.size() > 0) {
this.onDiagnostics.call(result.v1)

View File

@ -20,7 +20,7 @@ class EmbeddablePartsMap {
Objects.requireNonNull(globals)
Objects.requireNonNull(onDiagnostics)
parts.each {
this.put(it.path, new EmbeddablePart(it, globals, onDiagnostics, text))
this.put(it.path, new EmbeddablePart(it, globals, onDiagnostics, text, parts))
}
}

View File

@ -18,22 +18,30 @@ class GspPartRenderer implements PartRenderer {
Part part,
Map binding,
Map globals,
@Nullable EmbeddableText text = null
@Nullable EmbeddableText text = null,
Collection<Part> allParts
) {
Objects.requireNonNull(part)
Objects.requireNonNull(binding)
Objects.requireNonNull(globals)
Objects.requireNonNull(allParts)
def embeddedPartDiagnostics = []
try {
def result = engine.createTemplate(part.text).make([
binding: binding,
globals: globals,
parts: new EmbeddablePartsMap(allParts, globals, embeddedPartDiagnostics.&addAll, text),
tagBuilder: new DynamicTagBuilder(),
text: text
])
new Tuple2<>([], result.toString())
} catch (Exception e) {
def diagnostic = new Diagnostic(
"An exception occurred while rendering part ${ part.path }:\n${ e }",
e
)
new Tuple2<>(
[new Diagnostic("An exception occurred while rendering part ${ part.path }:\n${ e }", e)],
[diagnostic, *embeddedPartDiagnostics],
''
)
}

View File

@ -10,7 +10,8 @@ interface PartRenderer {
Part part,
Map binding,
Map globals,
@Nullable EmbeddableText text
@Nullable EmbeddableText text,
Collection<Part> allParts
)
}

View File

@ -3,7 +3,9 @@ package com.jessebrault.ssg.part
import com.jessebrault.ssg.Diagnostic
import com.jessebrault.ssg.text.*
import org.junit.jupiter.api.Test
import org.mockito.Mock
import static com.jessebrault.ssg.testutil.DiagnosticsUtil.getDiagnosticsMessageSupplier
import static org.junit.jupiter.api.Assertions.assertEquals
import static org.junit.jupiter.api.Assertions.assertTrue
import static org.mockito.ArgumentMatchers.any
@ -28,7 +30,7 @@ class GspPartRendererTests {
@Test
void rendersWithNoBindingOrGlobals() {
def part = new Part('', null, 'Hello, World!')
def r = this.renderer.render(part, [:], [:], null)
def r = this.renderer.render(part, [:], [:], null, [part])
assertTrue(r.v1.size() == 0)
assertEquals('Hello, World!', r.v2)
}
@ -36,7 +38,13 @@ class GspPartRendererTests {
@Test
void rendersWithBinding() {
def part = new Part('', null, "<%= binding['greeting'] %>")
def r = this.renderer.render(part, [greeting: 'Hello, World!'], [:], null)
def r = this.renderer.render(
part,
[greeting: 'Hello, World!'],
[:],
null,
[part]
)
assertTrue(r.v1.size() == 0)
assertEquals('Hello, World!', r.v2)
}
@ -44,7 +52,13 @@ class GspPartRendererTests {
@Test
void rendersWithGlobals() {
def part = new Part(null, null, "<%= globals['greeting'] %>")
def r = this.renderer.render(part, [:], [greeting: 'Hello, World!'], null)
def r = this.renderer.render(
part,
[:],
[greeting: 'Hello, World!'],
null,
[part]
)
assertTrue(r.v1.size() == 0)
assertEquals('Hello, World!', r.v2)
}
@ -61,7 +75,8 @@ class GspPartRendererTests {
mockRenderableText('Hello, World!'),
[:],
{ Collection<Diagnostic> diagnostics -> textDiagnostics.addAll(diagnostics) }
)
),
[part]
)
assertTrue(textDiagnostics.isEmpty())
assertTrue(r.v1.isEmpty())
@ -71,9 +86,19 @@ class GspPartRendererTests {
@Test
void tagBuilderAvailable() {
def part = new Part('', null, '<%= tagBuilder.test() %>')
def r = this.renderer.render(part, [:], [:], null)
def r = this.renderer.render(part, [:], [:], null, [part])
assertTrue(r.v1.isEmpty())
assertEquals('<test />', r.v2)
}
@Test
void allPartsAvailable() {
def partType = new PartType(['.gsp'], this.renderer)
def part0 = new Part('part0.gsp', partType, '<%= parts["part1.gsp"].render() %>')
def part1 = new Part('part1.gsp', partType, 'Hello, World!')
def r = this.renderer.render(part0, [:], [:], null, [part0, part1])
assertTrue(r.v1.isEmpty(), getDiagnosticsMessageSupplier(r.v1))
assertEquals('Hello, World!', r.v2)
}
}

View File

@ -0,0 +1,18 @@
package com.jessebrault.ssg.testutil
import com.jessebrault.ssg.Diagnostic
class DiagnosticsUtil {
static Closure<String> getDiagnosticsMessageSupplier(Collection<Diagnostic> diagnostics) {
return {
diagnostics.collect {
def writer = new StringWriter()
it.exception.printStackTrace(new PrintWriter(writer))
def stackTrace = writer.toString()
"$it.message\n$stackTrace"
}.join('\n')
}
}
}