Major refactoring and api changes.

This commit is contained in:
JesseBrault0709 2023-01-08 17:31:26 -06:00
parent 829ec4698e
commit 27ae22d5eb
26 changed files with 309 additions and 136 deletions

View File

@ -102,10 +102,22 @@ class StaticSiteGeneratorCli implements Callable<Integer> {
// Generate
def ssg = new SimpleStaticSiteGenerator(config)
ssg.generate(new File('build'), globals)
def result = ssg.generate(globals)
// Exit
return 0
if (result.v1.size() > 0) {
result.v1.each {
logger.error(it.message)
}
return 1
} else {
def buildDir = new File('build')
result.v2.each {
def target = new File(buildDir, it.path + '.html')
target.createParentDirectories()
target.write(it.html)
}
return 0
}
}
}

View File

@ -19,6 +19,9 @@ dependencies {
// https://mvnrepository.com/artifact/org.commonmark/commonmark-ext-yaml-front-matter
implementation 'org.commonmark:commonmark-ext-yaml-front-matter:0.21.0'
/**
* Logging
*/
// https://mvnrepository.com/artifact/org.slf4j/slf4j-api
implementation 'org.slf4j:slf4j-api:1.7.36'

View File

@ -0,0 +1,18 @@
package com.jessebrault.ssg
import groovy.transform.EqualsAndHashCode
import groovy.transform.TupleConstructor
@TupleConstructor
@EqualsAndHashCode
class Diagnostic {
String message
Exception exception
@Override
String toString() {
"Diagnostic(message: ${ this.message }, exception: ${ this.exception })"
}
}

View File

@ -0,0 +1,20 @@
package com.jessebrault.ssg
import groovy.transform.EqualsAndHashCode
import groovy.transform.NullCheck
import groovy.transform.TupleConstructor
@TupleConstructor(includeFields = true, defaults = false)
@NullCheck
@EqualsAndHashCode
class GeneratedPage {
String path
String html
@Override
String toString() {
"GeneratedPage(path: ${ this.path })"
}
}

View File

@ -1,5 +1,6 @@
package com.jessebrault.ssg
import com.jessebrault.ssg.text.FrontMatter
import groovy.transform.EqualsAndHashCode
import groovy.transform.NullCheck
import groovy.transform.TupleConstructor
@ -20,8 +21,8 @@ class SimpleStaticSiteGenerator implements StaticSiteGenerator {
private final Config config
@Override
void generate(File buildDir, Map globals) {
logger.trace(enter, 'buildDir: {}, globals: {}', buildDir, globals)
Tuple2<Collection<Diagnostic>, Collection<GeneratedPage>> generate(Map globals) {
logger.trace(enter, 'globals: {}', globals)
// Get all texts, templates, parts, and specialPages
def texts = this.config.textProviders.collectMany { it.getTextFiles() }
@ -31,64 +32,91 @@ class SimpleStaticSiteGenerator implements StaticSiteGenerator {
logger.debug('\n\ttexts: {}\n\ttemplates: {}\n\tparts: {}\n\tspecialPages: {}', texts, templates, parts, specialPages)
// Define output function
def outputPage = { String path, String result ->
def outFile = new File(buildDir, path + '.html')
if (outFile.exists()) {
logger.info('outFile {} already exists, deleting', outFile)
outFile.delete()
}
outFile.createParentDirectories()
logger.info('writing result to {}', outFile)
outFile.write(result)
}
Collection<Diagnostic> diagnostics = []
Collection<GeneratedPage> generatedPages = []
// Generate pages from each text
texts.each {
logger.trace(enter, 'text: {}', it)
logger.info('processing text: {}', it.path)
// Render the text (i.e., transform text to html)
def renderedText = it.type.renderer.render(it.text, globals)
def textRenderResult = it.type.renderer.render(it, globals)
String renderedText
if (textRenderResult.v1.size() > 0) {
logger.debug('diagnostics for rendering {}: {}', it.path, textRenderResult.v1)
diagnostics.addAll(textRenderResult.v1)
logger.trace(exit, '')
return
} else {
renderedText = textRenderResult.v2
logger.debug('renderedText: {}', renderedText)
}
// Extract frontMatter from text
def frontMatter = it.type.frontMatterGetter.get(it.text)
logger.debug('frontMatter: {}', frontMatter)
def frontMatterResult = it.type.frontMatterGetter.get(it)
FrontMatter frontMatter
if (frontMatterResult.v1.size() > 0) {
logger.debug('diagnostics for getting frontMatter for {}: {}', it.path, frontMatterResult.v1)
diagnostics.addAll(frontMatterResult.v1)
logger.trace(exit, '')
return
} else {
frontMatter = frontMatterResult.v2
logger.debug('frontMatter: {}', frontMatter)
}
// Find the appropriate template from the frontMatter
def desiredTemplate = frontMatter['template']
logger.debug('desiredTemplate name: {}', desiredTemplate)
if (desiredTemplate == null) {
throw new IllegalArgumentException('in text ' + it.path + ' frontMatter.template must not be null')
if (desiredTemplate == null || desiredTemplate.isEmpty() || desiredTemplate.isBlank()) {
diagnostics << new Diagnostic('in textFile ' + it.path + ' frontMatter.template must not be empty, blank, or missing', null)
logger.trace(exit, '')
return
}
if (desiredTemplate.isEmpty() || desiredTemplate.isBlank()) {
throw new IllegalArgumentException('in text ' + it.path + ' frontMatter.template must not be empty, blank, or missing')
}
def template = templates.find {
it.relativePath == desiredTemplate
}
logger.debug('template: {}', template)
def template = templates.find { it.path == desiredTemplate }
if (template == null) {
throw new IllegalArgumentException('in textFile' + it.path + ' unknown template: ' + desiredTemplate)
diagnostics << new Diagnostic('in textFile' + it.path + ' frontMatter.template references an unknown template: ' + desiredTemplate, null)
logger.trace(exit, '')
return
}
logger.debug('found template: {}', template)
// Render the template using the result of rendering the text earlier
def result = template.type.renderer.render(template, frontMatter, renderedText, parts, globals)
def templateRenderResult = template.type.renderer.render(template, frontMatter, renderedText, parts, globals)
String renderedTemplate
if (templateRenderResult.v1.size() > 0) {
diagnostics.addAll(templateRenderResult.v1)
logger.trace(exit, '')
return
} else {
renderedTemplate = templateRenderResult.v2
}
// Output the result to the outfile, an .html file
outputPage(it.path, result)
// Create a GeneratedPage
generatedPages << new GeneratedPage(it.path, renderedTemplate)
}
// Generate special pages
specialPages.each {
logger.info('processing specialPage: {}', it)
logger.info('processing specialPage: {}', it.path)
def result = it.type.renderer.render(it.text, texts, parts, globals)
def specialPageRenderResult = it.type.renderer.render(it, texts, parts, globals)
String renderedSpecialPage
if (specialPageRenderResult.v1.size() > 0) {
diagnostics.addAll(specialPageRenderResult.v1)
logger.trace(exit, '')
return
} else {
renderedSpecialPage = specialPageRenderResult.v2
}
// Output result to file
outputPage(it.path, result)
// Create a GeneratedPage
generatedPages << new GeneratedPage(it.path, renderedSpecialPage)
}
logger.trace(exit, '')
logger.trace(exit, '\n\tdiagnostics: {}\n\tgeneratedPages: {}', diagnostics, generatedPages)
new Tuple2<>(diagnostics, generatedPages)
}
@Override

View File

@ -1,5 +1,5 @@
package com.jessebrault.ssg
interface StaticSiteGenerator {
void generate(File buildDir, Map globals)
Tuple2<Collection<Diagnostic>, Collection<GeneratedPage>> generate(Map globals)
}

View File

@ -11,9 +11,16 @@ class EmbeddablePart {
private final Part part
private final Map globals
private final Closure onDiagnostics
String render(Map binding = [:]) {
part.type.renderer.render(this.part.text, binding, this.globals)
def result = part.type.renderer.render(this.part, binding, this.globals)
if (result.v1.size() > 0) {
this.onDiagnostics.call(result.v1)
''
} else {
result.v2
}
}
@Override

View File

@ -1,17 +1,18 @@
package com.jessebrault.ssg.part
import groovy.transform.EqualsAndHashCode
import groovy.transform.NullCheck
@NullCheck
@EqualsAndHashCode(includeFields = true)
class EmbeddablePartsMap {
@Delegate
private final Map<String, EmbeddablePart> partsMap = [:]
EmbeddablePartsMap(Collection<Part> parts, Map globals) {
Objects.requireNonNull(parts)
EmbeddablePartsMap(Collection<Part> parts, Map globals, Closure onDiagnostics) {
parts.each {
this.put(it.path, new EmbeddablePart(it, globals))
this.put(it.path, new EmbeddablePart(it, globals, onDiagnostics))
}
}

View File

@ -1,5 +1,6 @@
package com.jessebrault.ssg.part
import com.jessebrault.ssg.Diagnostic
import groovy.text.GStringTemplateEngine
import groovy.text.TemplateEngine
import groovy.transform.EqualsAndHashCode
@ -10,11 +11,16 @@ class GspPartRenderer implements PartRenderer {
private static final TemplateEngine engine = new GStringTemplateEngine()
@Override
String render(String partText, Map binding, Map globals) {
engine.createTemplate(partText).make([
binding: binding,
globals: globals
])
Tuple2<Collection<Diagnostic>, String> render(Part part, Map binding, Map globals) {
try {
def result = engine.createTemplate(part.text).make([
binding: binding,
globals: globals
])
new Tuple2<>([], result.toString())
} catch (Exception e) {
new Tuple2<>([new Diagnostic("An exception occurred while rendering part ${ part.path }:\n${ e }", e)], '')
}
}
@Override

View File

@ -1,5 +1,7 @@
package com.jessebrault.ssg.part
import com.jessebrault.ssg.Diagnostic
interface PartRenderer {
String render(String partText, Map binding, Map globals)
Tuple2<Collection<Diagnostic>, String> render(Part part, Map binding, Map globals)
}

View File

@ -1,5 +1,6 @@
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.text.EmbeddableTextsCollection
@ -7,24 +8,31 @@ import com.jessebrault.ssg.text.Text
import groovy.text.GStringTemplateEngine
import groovy.text.TemplateEngine
import groovy.transform.EqualsAndHashCode
import groovy.transform.NullCheck
@NullCheck
@EqualsAndHashCode
class GspSpecialPageRenderer implements SpecialPageRenderer {
private static final TemplateEngine engine = new GStringTemplateEngine()
@Override
String render(String text, Collection<Text> texts, Collection<Part> parts, Map globals) {
Objects.requireNonNull(text)
Objects.requireNonNull(texts)
Objects.requireNonNull(parts)
Objects.requireNonNull(globals)
engine.createTemplate(text).make([
globals: globals,
parts: new EmbeddablePartsMap(parts, globals),
texts: new EmbeddableTextsCollection(texts, globals)
])
Tuple2<Collection<Diagnostic>, String> render(SpecialPage specialPage, Collection<Text> texts, Collection<Part> parts, Map globals) {
try {
Collection<Diagnostic> diagnostics = []
def result = engine.createTemplate(specialPage.text).make([
globals: globals,
parts: new EmbeddablePartsMap(parts, globals, { Collection<Diagnostic> partDiagnostics ->
diagnostics.addAll(partDiagnostics)
}),
texts: new EmbeddableTextsCollection(texts, globals, { Collection<Diagnostic> textDiagnostics ->
diagnostics.addAll(textDiagnostics)
})
])
new Tuple2<>(diagnostics, result.toString())
} catch (Exception e) {
new Tuple2<>([new Diagnostic("An exception occurred while rendering specialPage ${ specialPage.path }:\n${ e }", e)], '')
}
}
@Override

View File

@ -1,12 +1,13 @@
package com.jessebrault.ssg.specialpage
import com.jessebrault.ssg.Diagnostic
import com.jessebrault.ssg.part.Part
import com.jessebrault.ssg.text.Text
interface SpecialPageRenderer {
String render(
String text,
Tuple2<Collection<Diagnostic>, String> render(
SpecialPage specialPage,
Collection<Text> texts,
Collection <Part> parts,
Map globals

View File

@ -1,31 +1,42 @@
package com.jessebrault.ssg.template
import com.jessebrault.ssg.Diagnostic
import com.jessebrault.ssg.part.Part
import com.jessebrault.ssg.part.EmbeddablePartsMap
import com.jessebrault.ssg.text.FrontMatter
import groovy.text.GStringTemplateEngine
import groovy.text.TemplateEngine
import groovy.transform.EqualsAndHashCode
import groovy.transform.NullCheck
@NullCheck
@EqualsAndHashCode
class GspTemplateRenderer implements TemplateRenderer {
private static final TemplateEngine engine = new GStringTemplateEngine()
@Override
String render(
Tuple2<Collection<Diagnostic>, String> render(
Template template,
FrontMatter frontMatter,
String text,
Collection<Part> parts,
Map globals
) {
engine.createTemplate(template.text).make([
frontMatter: frontMatter,
globals: globals,
parts: new EmbeddablePartsMap(parts, globals),
text: text
])
try {
Collection<Diagnostic> diagnostics = []
def result = engine.createTemplate(template.text).make([
frontMatter: frontMatter,
globals: globals,
parts: new EmbeddablePartsMap(parts, globals, { Collection<Diagnostic> partDiagnostics ->
diagnostics.addAll(partDiagnostics)
}),
text: text
])
new Tuple2<>(diagnostics, result.toString())
} catch (Exception e) {
new Tuple2<>([new Diagnostic("An exception occurred while rendering Template ${ template.path }:\n${ e }", e)], '')
}
}
@Override

View File

@ -10,12 +10,12 @@ import groovy.transform.TupleConstructor
class Template {
String text
String relativePath
String path
TemplateType type
@Override
String toString() {
"Template(path: ${ this.relativePath }, type: ${ this.type })"
"Template(path: ${ this.path }, type: ${ this.type })"
}
}

View File

@ -1,11 +1,12 @@
package com.jessebrault.ssg.template
import com.jessebrault.ssg.Diagnostic
import com.jessebrault.ssg.part.Part
import com.jessebrault.ssg.text.FrontMatter
interface TemplateRenderer {
String render(
Tuple2<Collection<Diagnostic>, String> render(
Template template,
FrontMatter frontMatter,
String text,

View File

@ -8,19 +8,32 @@ import groovy.transform.TupleConstructor
@TupleConstructor(includeFields = true, defaults = false)
@NullCheck
@EqualsAndHashCode(includeFields = true)
class EmbeddableText {
class EmbeddableText {
private final Text text
private final Map globals
private final Closure onDiagnostics
@Memoized
String render() {
this.text.type.renderer.render(this.text.text, globals)
def result = this.text.type.renderer.render(this.text, globals)
if (result.v1.size() > 0) {
this.onDiagnostics.call(result.v1)
''
} else {
result.v2
}
}
@Memoized
FrontMatter getFrontMatter() {
this.text.type.frontMatterGetter.get(this.text.text)
def result = this.text.type.frontMatterGetter.get(this.text)
if (result.v1.size() > 0) {
this.onDiagnostics.call(result.v1)
new FrontMatter([:])
} else {
result.v2
}
}
String getPath() {

View File

@ -1,16 +1,18 @@
package com.jessebrault.ssg.text
import groovy.transform.EqualsAndHashCode
import groovy.transform.NullCheck
@NullCheck
@EqualsAndHashCode(includeFields = true)
class EmbeddableTextsCollection {
@Delegate
private final Collection<EmbeddableText> embeddableTexts = []
EmbeddableTextsCollection(Collection<Text> texts, Map globals) {
EmbeddableTextsCollection(Collection<Text> texts, Map globals, Closure onDiagnostics) {
Objects.requireNonNull(texts).each {
this << new EmbeddableText(it, globals)
this << new EmbeddableText(it, globals, onDiagnostics)
}
}

View File

@ -1,5 +1,7 @@
package com.jessebrault.ssg.text
import com.jessebrault.ssg.Diagnostic
interface FrontMatterGetter {
FrontMatter get(String text)
Tuple2<Collection<Diagnostic>, FrontMatter> get(Text text)
}

View File

@ -1,10 +1,13 @@
package com.jessebrault.ssg.text
import com.jessebrault.ssg.Diagnostic
import groovy.transform.EqualsAndHashCode
import groovy.transform.NullCheck
import org.commonmark.ext.front.matter.YamlFrontMatterExtension
import org.commonmark.ext.front.matter.YamlFrontMatterVisitor
import org.commonmark.parser.Parser
@NullCheck
@EqualsAndHashCode
class MarkdownFrontMatterGetter implements FrontMatterGetter {
@ -13,11 +16,15 @@ class MarkdownFrontMatterGetter implements FrontMatterGetter {
.build()
@Override
FrontMatter get(String text) {
def node = parser.parse(text)
def v = new YamlFrontMatterVisitor()
node.accept(v)
new FrontMatter(v.data)
Tuple2<Collection<Diagnostic>, FrontMatter> get(Text text) {
try {
def node = parser.parse(text.text)
def v = new YamlFrontMatterVisitor()
node.accept(v)
new Tuple2([], new FrontMatter(v.data))
} catch (Exception e) {
new Tuple2<>([new Diagnostic("An exception occured while parsing frontMatter for ${ text.path }:\n${ e }", e)], new FrontMatter([:]))
}
}
@Override

View File

@ -1,10 +1,13 @@
package com.jessebrault.ssg.text
import com.jessebrault.ssg.Diagnostic
import groovy.transform.EqualsAndHashCode
import groovy.transform.NullCheck
import org.commonmark.ext.front.matter.YamlFrontMatterExtension
import org.commonmark.parser.Parser
import org.commonmark.renderer.html.HtmlRenderer
@NullCheck
@EqualsAndHashCode
class MarkdownTextRenderer implements TextRenderer {
@ -14,8 +17,12 @@ class MarkdownTextRenderer implements TextRenderer {
private static final HtmlRenderer htmlRenderer = HtmlRenderer.builder().build()
@Override
String render(String text, Map globals) {
htmlRenderer.render(parser.parse(text))
Tuple2<Collection<Diagnostic>, String> render(Text text, Map globals) {
try {
new Tuple2<>([], htmlRenderer.render(parser.parse(text.text)))
} catch (Exception e) {
new Tuple2<>([new Diagnostic("There was an exception while rendering ${ text.path }:\n${ e }", e)], '')
}
}
@Override

View File

@ -1,13 +1,7 @@
package com.jessebrault.ssg.text
import com.jessebrault.ssg.Diagnostic
interface TextRenderer {
/**
* Renders the text from its raw form to html.
*
* @param text in raw form
* @return the rendered text in html
*/
String render(String text, Map globals)
Tuple2<Collection<Diagnostic>, String> render(Text text, Map globals)
}

View File

@ -14,12 +14,13 @@ import com.jessebrault.ssg.text.MarkdownTextRenderer
import com.jessebrault.ssg.text.TextFileTextsProvider
import com.jessebrault.ssg.text.TextType
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.Test
import static org.junit.jupiter.api.Assertions.assertEquals
import static org.junit.jupiter.api.Assertions.assertTrue
class StaticSiteGeneratorTests {
class SimpleStaticSiteGeneratorIntegrationTests {
private File partsDir
private File templatesDir
@ -59,12 +60,14 @@ class StaticSiteGeneratorTests {
new File(this.textsDir, 'test.md').write('---\ntemplate: test.gsp\n---\n**Hello, World!**')
new File(this.templatesDir, 'test.gsp').write('<%= text %>')
def buildDir = File.createTempDir()
this.ssg.generate(buildDir, [:])
def result = this.ssg.generate([:])
def outFile = new File(buildDir, 'test.html')
assertTrue(outFile.exists())
assertEquals('<p><strong>Hello, World!</strong></p>\n', outFile.text)
assertTrue(result.v1.size() == 0)
assertTrue(result.v2.size() == 1)
def p0 = result.v2[0]
assertEquals('test', p0.path)
assertEquals('<p><strong>Hello, World!</strong></p>\n', p0.html)
}
@Test
@ -77,26 +80,31 @@ class StaticSiteGeneratorTests {
new File(this.templatesDir, 'nested.gsp').write('<%= text %>')
def buildDir = File.createTempDir()
this.ssg.generate(buildDir, [:])
def result = this.ssg.generate([:])
def outFile = new File(new File(buildDir, 'nested'), 'nested.html')
assertTrue(outFile.exists())
assertEquals('<p><strong>Hello, World!</strong></p>\n', outFile.text)
assertTrue(result.v1.size() == 0)
assertTrue(result.v2.size() == 1)
def p0 = result.v2[0]
assertEquals('nested/nested', p0.path)
assertEquals('<p><strong>Hello, World!</strong></p>\n', p0.html)
}
@Test
@Disabled('have to figure out what to do when we need just a plain text for a special page')
void outputsSpecialPage() {
new FileTreeBuilder(this.specialPagesDir).file('special.gsp', $/<%= texts.find { it.path == 'test' }.render() %>/$)
new FileTreeBuilder(this.templatesDir).file('template.gsp', '<%= 1 + 1 %>')
new FileTreeBuilder(this.textsDir).file('test.md', '---\ntemplate: template.gsp\n---\nHello, World!')
new FileTreeBuilder(this.textsDir).file('test.md', 'Hello, World!')
def buildDir = File.createTempDir()
this.ssg.generate(buildDir, [:])
def result = this.ssg.generate([:])
def outFile = new File(buildDir, 'special.html')
assertTrue(outFile.exists())
assertEquals('<p>Hello, World!</p>\n', outFile.text)
assertEquals(0, result.v1.size())
assertEquals(2, result.v2.size())
def p0 = result.v2[0]
assertEquals('special', p0.path)
assertEquals('<p>Hello, World!</p>\n', p0.html)
}
}

View File

@ -3,6 +3,7 @@ package com.jessebrault.ssg.part
import org.junit.jupiter.api.Test
import static org.junit.jupiter.api.Assertions.assertEquals
import static org.junit.jupiter.api.Assertions.assertTrue
class GspPartRendererTests {
@ -10,20 +11,26 @@ class GspPartRendererTests {
@Test
void rendersWithNoBindingOrGlobals() {
def r = this.renderer.render('Hello, World!', [:], [:])
assertEquals('Hello, World!', r)
def part = new Part('', null, 'Hello, World!')
def r = this.renderer.render(part, [:], [:])
assertTrue(r.v1.size() == 0)
assertEquals('Hello, World!', r.v2)
}
@Test
void rendersWithBinding() {
def r = this.renderer.render("<%= binding['greeting'] %>", [greeting: 'Hello, World!'], [:])
assertEquals('Hello, World!', r)
def part = new Part('', null, "<%= binding['greeting'] %>")
def r = this.renderer.render(part, [greeting: 'Hello, World!'], [:])
assertTrue(r.v1.size() == 0)
assertEquals('Hello, World!', r.v2)
}
@Test
void rendersWithGlobals() {
def r = this.renderer.render("<%= globals['greeting'] %>", [:], [greeting: 'Hello, World!'])
assertEquals('Hello, World!', r)
def part = new Part(null, null, "<%= globals['greeting'] %>")
def r = this.renderer.render(part, [:], [greeting: 'Hello, World!'])
assertTrue(r.v1.size() == 0)
assertEquals('Hello, World!', r.v2)
}
}

View File

@ -13,6 +13,7 @@ import org.mockito.Mock
import org.mockito.junit.jupiter.MockitoExtension
import static org.junit.jupiter.api.Assertions.assertEquals
import static org.junit.jupiter.api.Assertions.assertTrue
import static org.mockito.ArgumentMatchers.any
import static org.mockito.ArgumentMatchers.argThat
import static org.mockito.Mockito.when
@ -24,39 +25,47 @@ class GspSpecialPageRendererTests {
@Test
void rendersGlobal() {
def specialPage = new SpecialPage("<%= globals['greeting'] %>", null, null)
def globals = [greeting: 'Hello, World!']
def r = this.renderer.render("<%= globals['greeting'] %>", [], [], globals)
assertEquals('Hello, World!', r)
def r = this.renderer.render(specialPage, [], [], globals)
assertTrue(r.v1.size() == 0)
assertEquals('Hello, World!', r.v2)
}
@Test
void rendersPartWithNoBinding(@Mock PartRenderer partRenderer) {
when(partRenderer.render(any(), any(), any())).thenReturn('Hello, World!')
when(partRenderer.render(any(), any(), any())).thenReturn(new Tuple2<>([], 'Hello, World!'))
def partType = new PartType([], partRenderer)
def part = new Part('test', partType , '')
def r = this.renderer.render("<%= parts['test'].render() %>", [], [part], [:])
assertEquals('Hello, World!', r)
def specialPage = new SpecialPage("<%= parts['test'].render() %>", null, null)
def r = this.renderer.render(specialPage, [], [part], [:])
assertTrue(r.v1.size() == 0)
assertEquals('Hello, World!', r.v2)
}
@Test
void rendersPartWithBinding(@Mock PartRenderer partRenderer) {
when(partRenderer.render(any(), argThat { Map m -> m.get('greeting') == 'Hello, World!'}, any())).thenReturn('Hello, World!')
when(partRenderer.render(any(), argThat { Map m -> m.get('greeting') == 'Hello, World!'}, any())).thenReturn(new Tuple2<>([], 'Hello, World!'))
def partType = new PartType([], partRenderer)
def part = new Part('test', partType, '')
def r = this.renderer.render("<%= parts['test'].render([greeting: 'Hello, World!'])", [], [part], [:])
assertEquals('Hello, World!', r)
def specialPage = new SpecialPage("<%= parts['test'].render([greeting: 'Hello, World!'])", null, null)
def r = this.renderer.render(specialPage, [], [part], [:])
assertTrue(r.v1.size() == 0)
assertEquals('Hello, World!', r.v2)
}
@Test
void rendersText(@Mock TextRenderer textRenderer, @Mock FrontMatterGetter frontMatterGetter) {
when(textRenderer.render(any(), any())).thenReturn('<p><strong>Hello, World!</strong></p>\n')
when(textRenderer.render(any(), any())).thenReturn(new Tuple2<>([], '<p><strong>Hello, World!</strong></p>\n'))
def textType = new TextType([], textRenderer, frontMatterGetter)
def text = new Text('', 'test', textType)
def r = this.renderer.render("<%= texts.find { it.path == 'test' }.render() %>", [text], [], [:])
assertEquals('<p><strong>Hello, World!</strong></p>\n', r)
def specialPage = new SpecialPage("<%= texts.find { it.path == 'test' }.render() %>", null, null)
def r = this.renderer.render(specialPage, [text], [], [:])
assertTrue(r.v1.size() == 0)
assertEquals('<p><strong>Hello, World!</strong></p>\n', r.v2)
}
}

View File

@ -10,6 +10,7 @@ import org.mockito.Mock
import org.mockito.junit.jupiter.MockitoExtension
import static org.junit.jupiter.api.Assertions.assertEquals
import static org.junit.jupiter.api.Assertions.assertTrue
import static org.mockito.ArgumentMatchers.any
import static org.mockito.ArgumentMatchers.argThat
import static org.mockito.Mockito.when
@ -27,12 +28,13 @@ class GspTemplateRendererTests {
null
)
when(partRenderer.render(any(), any(), any())).thenReturn('Hello, World!')
when(partRenderer.render(any(), any(), any())).thenReturn(new Tuple2<>([], 'Hello, World!'))
def partType = new PartType([], partRenderer)
def part = new Part('test', partType, null)
def r = this.renderer.render(template, new FrontMatter([:]), '', [part], [:])
assertEquals('Hello, World!', r)
assertTrue(r.v1.size() == 0)
assertEquals('Hello, World!', r.v2)
}
@Test
@ -43,33 +45,37 @@ class GspTemplateRendererTests {
null
)
when(partRenderer.render(any(), argThat { Map m -> m.get('person') == 'World' }, any())).thenReturn('Hello, World!')
when(partRenderer.render(any(), argThat { Map m -> m.get('person') == 'World' }, any())).thenReturn(new Tuple2<>([], 'Hello, World!'))
def partType = new PartType([], partRenderer)
def part = new Part('greeting', partType, null)
def r = this.renderer.render(template, new FrontMatter([:]), '', [part], [:])
assertEquals('Hello, World!', r)
assertTrue(r.v1.size() == 0)
assertEquals('Hello, World!', r.v2)
}
@Test
void rendersFrontMatter() {
def template = new Template("<%= frontMatter['title'] %>", null, null)
def r = this.renderer.render(template, new FrontMatter([title: ['Hello!']]), '', [], [:])
assertEquals('Hello!', r)
assertTrue(r.v1.size() == 0)
assertEquals('Hello!', r.v2)
}
@Test
void rendersGlobal() {
def template = new Template("<%= globals['test'] %>", null, null)
def r = this.renderer.render(template, new FrontMatter([:]), '', [], [test: 'Hello, World!'])
assertEquals('Hello, World!', r)
assertTrue(r.v1.size() == 0)
assertEquals('Hello, World!', r.v2)
}
@Test
void rendersText() {
def template = new Template('<%= text %>', null, null)
def r = this.renderer.render(template, new FrontMatter([:]), 'Hello, World!', [], [:])
assertEquals('Hello, World!', r)
assertTrue(r.v1.size() == 0)
assertEquals('Hello, World!', r.v2)
}
}

View File

@ -25,7 +25,7 @@ class PageTemplatesProviderTests {
def r = this.templatesProvider.getTemplates()
assertEquals(1, r.size())
def t0 = r[0]
assertEquals('test.gsp', t0.relativePath)
assertEquals('test.gsp', t0.path)
assertEquals('<% out << text %>', t0.text)
assertEquals(gspType, t0.type)
}
@ -41,7 +41,7 @@ class PageTemplatesProviderTests {
def r = this.templatesProvider.getTemplates()
assertEquals(1, r.size())
def t0 = r[0]
assertEquals('nested/nested.gsp', t0.relativePath)
assertEquals('nested/nested.gsp', t0.path)
assertEquals('<%= text %>', t0.text)
assertEquals(gspType, t0.type)
}