diff --git a/lib/src/main/groovy/com/jessebrault/ssg/part/EmbeddablePart.groovy b/lib/src/main/groovy/com/jessebrault/ssg/part/EmbeddablePart.groovy index 274716a..e696335 100644 --- a/lib/src/main/groovy/com/jessebrault/ssg/part/EmbeddablePart.groovy +++ b/lib/src/main/groovy/com/jessebrault/ssg/part/EmbeddablePart.groovy @@ -20,13 +20,16 @@ class EmbeddablePart { private final Collection allParts + private final String path + String render(Map binding = [:]) { def result = part.type.renderer.render( this.part, binding, this.globals, this.text, - this.allParts + this.allParts, + this.path ) if (result.v1.size() > 0) { this.onDiagnostics.call(result.v1) diff --git a/lib/src/main/groovy/com/jessebrault/ssg/part/EmbeddablePartsMap.groovy b/lib/src/main/groovy/com/jessebrault/ssg/part/EmbeddablePartsMap.groovy index efff763..290f8ee 100644 --- a/lib/src/main/groovy/com/jessebrault/ssg/part/EmbeddablePartsMap.groovy +++ b/lib/src/main/groovy/com/jessebrault/ssg/part/EmbeddablePartsMap.groovy @@ -14,13 +14,14 @@ class EmbeddablePartsMap { Collection parts, Map globals, Closure onDiagnostics, - @Nullable EmbeddableText text = null + @Nullable EmbeddableText text = null, + String path ) { Objects.requireNonNull(parts) Objects.requireNonNull(globals) Objects.requireNonNull(onDiagnostics) parts.each { - this.put(it.path, new EmbeddablePart(it, globals, onDiagnostics, text, parts)) + this.put(it.path, new EmbeddablePart(it, globals, onDiagnostics, text, parts, path)) } } 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 1e92479..f4716f7 100644 --- a/lib/src/main/groovy/com/jessebrault/ssg/part/GspPartRenderer.groovy +++ b/lib/src/main/groovy/com/jessebrault/ssg/part/GspPartRenderer.groovy @@ -3,6 +3,7 @@ package com.jessebrault.ssg.part import com.jessebrault.ssg.Diagnostic import com.jessebrault.ssg.tagbuilder.DynamicTagBuilder import com.jessebrault.ssg.text.EmbeddableText +import com.jessebrault.ssg.url.PathBasedUrlBuilder import groovy.text.GStringTemplateEngine import groovy.text.TemplateEngine import groovy.transform.EqualsAndHashCode @@ -19,20 +20,24 @@ class GspPartRenderer implements PartRenderer { Map binding, Map globals, @Nullable EmbeddableText text = null, - Collection allParts + Collection allParts, + String path ) { Objects.requireNonNull(part) Objects.requireNonNull(binding) Objects.requireNonNull(globals) Objects.requireNonNull(allParts) + Objects.requireNonNull(path) def embeddedPartDiagnostics = [] try { def result = engine.createTemplate(part.text).make([ binding: binding, globals: globals, - parts: new EmbeddablePartsMap(allParts, globals, embeddedPartDiagnostics.&addAll, text), + parts: new EmbeddablePartsMap(allParts, globals, embeddedPartDiagnostics.&addAll, text, path), + path: path, tagBuilder: new DynamicTagBuilder(), - text: text + text: text, + urlBuilder: new PathBasedUrlBuilder(path) ]) new Tuple2<>([], result.toString()) } catch (Exception e) { diff --git a/lib/src/main/groovy/com/jessebrault/ssg/part/PartRenderer.groovy b/lib/src/main/groovy/com/jessebrault/ssg/part/PartRenderer.groovy index be508a5..7c7dc3c 100644 --- a/lib/src/main/groovy/com/jessebrault/ssg/part/PartRenderer.groovy +++ b/lib/src/main/groovy/com/jessebrault/ssg/part/PartRenderer.groovy @@ -11,7 +11,8 @@ interface PartRenderer { Map binding, Map globals, @Nullable EmbeddableText text, - Collection allParts + Collection allParts, + String path ) } 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 6810e24..df607f1 100644 --- a/lib/src/main/groovy/com/jessebrault/ssg/specialpage/GspSpecialPageRenderer.groovy +++ b/lib/src/main/groovy/com/jessebrault/ssg/specialpage/GspSpecialPageRenderer.groovy @@ -6,6 +6,7 @@ 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 com.jessebrault.ssg.url.PathBasedUrlBuilder import groovy.text.GStringTemplateEngine import groovy.text.TemplateEngine import groovy.transform.EqualsAndHashCode @@ -18,18 +19,23 @@ class GspSpecialPageRenderer implements SpecialPageRenderer { private static final TemplateEngine engine = new GStringTemplateEngine() @Override - Tuple2, String> render(SpecialPage specialPage, Collection texts, Collection parts, Map globals) { + Tuple2, String> render( + SpecialPage specialPage, + Collection texts, + Collection parts, + Map globals + ) { try { Collection diagnostics = [] def result = engine.createTemplate(specialPage.text).make([ globals: globals, - parts: new EmbeddablePartsMap(parts, globals, { Collection partDiagnostics -> - diagnostics.addAll(partDiagnostics) - }), + parts: new EmbeddablePartsMap(parts, globals, diagnostics.&addAll, specialPage.path), + path: specialPage.path, tagBuilder: new DynamicTagBuilder(), texts: new EmbeddableTextsCollection(texts, globals, { Collection textDiagnostics -> diagnostics.addAll(textDiagnostics) - }) + }), + urlBuilder: new PathBasedUrlBuilder(specialPage.path) ]) new Tuple2<>(diagnostics, result.toString()) } catch (Exception e) { 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 0e01342..901b90e 100644 --- a/lib/src/main/groovy/com/jessebrault/ssg/template/GspTemplateRenderer.groovy +++ b/lib/src/main/groovy/com/jessebrault/ssg/template/GspTemplateRenderer.groovy @@ -7,6 +7,7 @@ import com.jessebrault.ssg.tagbuilder.DynamicTagBuilder import com.jessebrault.ssg.text.EmbeddableText import com.jessebrault.ssg.text.FrontMatter import com.jessebrault.ssg.text.Text +import com.jessebrault.ssg.url.PathBasedUrlBuilder import groovy.text.GStringTemplateEngine import groovy.text.TemplateEngine import groovy.transform.EqualsAndHashCode @@ -36,9 +37,11 @@ class GspTemplateRenderer implements TemplateRenderer { def result = engine.createTemplate(template.text).make([ frontMatter: frontMatter, globals: globals, - parts: new EmbeddablePartsMap(parts, globals, onDiagnostics, embeddableText), + parts: new EmbeddablePartsMap(parts, globals, onDiagnostics, embeddableText, text.path), + path: text.path, tagBuilder: new DynamicTagBuilder(), - text: embeddableText + text: embeddableText, + urlBuilder: new PathBasedUrlBuilder(text.path) ]) new Tuple2<>(diagnostics, result.toString()) } catch (Exception e) { diff --git a/lib/src/main/groovy/com/jessebrault/ssg/url/PathBasedUrlBuilder.groovy b/lib/src/main/groovy/com/jessebrault/ssg/url/PathBasedUrlBuilder.groovy new file mode 100644 index 0000000..c4065f3 --- /dev/null +++ b/lib/src/main/groovy/com/jessebrault/ssg/url/PathBasedUrlBuilder.groovy @@ -0,0 +1,23 @@ +package com.jessebrault.ssg.url + +import java.nio.file.Path + +class PathBasedUrlBuilder implements UrlBuilder { + + private final Path fromDirectory + + PathBasedUrlBuilder(String fromFile) { + def fromFilePath = Path.of(fromFile) + if (fromFilePath.parent) { + this.fromDirectory = fromFilePath.parent + } else { + this.fromDirectory = Path.of('') + } + } + + @Override + String relative(String to) { + this.fromDirectory.relativize(Path.of(to)).toString() + } + +} diff --git a/lib/src/main/groovy/com/jessebrault/ssg/url/UrlBuilder.groovy b/lib/src/main/groovy/com/jessebrault/ssg/url/UrlBuilder.groovy new file mode 100644 index 0000000..d7a2a26 --- /dev/null +++ b/lib/src/main/groovy/com/jessebrault/ssg/url/UrlBuilder.groovy @@ -0,0 +1,5 @@ +package com.jessebrault.ssg.url + +interface UrlBuilder { + String relative(String to) +} \ No newline at end of file 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 48cfa42..49165ab 100644 --- a/lib/src/test/groovy/com/jessebrault/ssg/part/GspPartRendererTests.groovy +++ b/lib/src/test/groovy/com/jessebrault/ssg/part/GspPartRendererTests.groovy @@ -1,35 +1,22 @@ package com.jessebrault.ssg.part -import com.jessebrault.ssg.Diagnostic -import com.jessebrault.ssg.text.* +import com.jessebrault.ssg.text.EmbeddableText import org.junit.jupiter.api.Test +import static com.jessebrault.ssg.testutil.DiagnosticsUtil.assertEmptyDiagnostics import static com.jessebrault.ssg.testutil.DiagnosticsUtil.getDiagnosticsMessageSupplier +import static com.jessebrault.ssg.text.TextMocks.renderableText 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.Mockito.mock -import static org.mockito.Mockito.when class GspPartRendererTests { - /** - * TODO: move to a fixture - */ - private static Text mockRenderableText(String text) { - def textRenderer = mock(TextRenderer) - when(textRenderer.render(any(), any())).thenReturn(new Tuple2<>([], text)) - def frontMatterGetter = mock(FrontMatterGetter) - def excerptGetter = mock(ExcerptGetter) - new Text('', '', new TextType([], textRenderer, frontMatterGetter, excerptGetter)) - } - private final PartRenderer renderer = new GspPartRenderer() @Test void rendersWithNoBindingOrGlobals() { def part = new Part('', null, 'Hello, World!') - def r = this.renderer.render(part, [:], [:], null, [part]) + def r = this.renderer.render(part, [:], [:], null, [part], '') assertTrue(r.v1.size() == 0) assertEquals('Hello, World!', r.v2) } @@ -42,7 +29,8 @@ class GspPartRendererTests { [greeting: 'Hello, World!'], [:], null, - [part] + [part], + '' ) assertTrue(r.v1.size() == 0) assertEquals('Hello, World!', r.v2) @@ -56,7 +44,8 @@ class GspPartRendererTests { [:], [greeting: 'Hello, World!'], null, - [part] + [part], + '' ) assertTrue(r.v1.size() == 0) assertEquals('Hello, World!', r.v2) @@ -70,12 +59,9 @@ class GspPartRendererTests { part, [:], [:], - new EmbeddableText( - mockRenderableText('Hello, World!'), - [:], - { Collection diagnostics -> textDiagnostics.addAll(diagnostics) } - ), - [part] + new EmbeddableText(renderableText('Hello, World!'), [:], textDiagnostics.&addAll), + [part], + '' ) assertTrue(textDiagnostics.isEmpty()) assertTrue(r.v1.isEmpty()) @@ -85,7 +71,7 @@ class GspPartRendererTests { @Test void tagBuilderAvailable() { def part = new Part('', null, '<%= tagBuilder.test() %>') - def r = this.renderer.render(part, [:], [:], null, [part]) + def r = this.renderer.render(part, [:], [:], null, [part], '') assertTrue(r.v1.isEmpty()) assertEquals('', r.v2) } @@ -95,9 +81,39 @@ class GspPartRendererTests { 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]) + def r = this.renderer.render(part0, [:], [:], null, [part0, part1], '') assertTrue(r.v1.isEmpty(), getDiagnosticsMessageSupplier(r.v1)) assertEquals('Hello, World!', r.v2) } + @Test + void pathAvailableIfPresent() { + def part = new Part('', null, '<%= path %>') + def r = this.renderer.render( + part, + [:], + [:], + null, + [part], + 'test.md' + ) + assertEmptyDiagnostics(r) + assertEquals('test.md', r.v2) + } + + @Test + void urlBuilderAvailable() { + def part = new Part('', null, '<%= urlBuilder.relative("images/test.jpg") %>') + def r = this.renderer.render( + part, + [:], + [:], + null, + [part], + 'test.md' + ) + assertEmptyDiagnostics(r) + assertEquals('images/test.jpg', 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 df0a597..5a61fcb 100644 --- a/lib/src/test/groovy/com/jessebrault/ssg/specialpage/GspSpecialPageRendererTests.groovy +++ b/lib/src/test/groovy/com/jessebrault/ssg/specialpage/GspSpecialPageRendererTests.groovy @@ -9,8 +9,8 @@ import org.junit.jupiter.api.extension.ExtendWith import org.mockito.Mock import org.mockito.junit.jupiter.MockitoExtension +import static com.jessebrault.ssg.testutil.DiagnosticsUtil.assertEmptyDiagnostics 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 @@ -22,39 +22,41 @@ class GspSpecialPageRendererTests { @Test void rendersGlobal() { - def specialPage = new SpecialPage("<%= globals['greeting'] %>", null, null) + def specialPage = new SpecialPage("<%= globals['greeting'] %>", 'test.gsp', null) def globals = [greeting: 'Hello, World!'] def r = this.renderer.render(specialPage, [], [], globals) - assertTrue(r.v1.size() == 0) + assertEmptyDiagnostics(r) assertEquals('Hello, World!', r.v2) } @Test void rendersPartWithNoBinding(@Mock PartRenderer partRenderer) { - when(partRenderer.render(any(), any(), any(), any())).thenReturn(new Tuple2<>([], 'Hello, World!')) + when(partRenderer.render(any(), any(), any(), any(), any(), any())) + .thenReturn(new Tuple2<>([], 'Hello, World!')) def partType = new PartType([], partRenderer) def part = new Part('test', partType , '') - def specialPage = new SpecialPage("<%= parts['test'].render() %>", null, null) + def specialPage = new SpecialPage("<%= parts['test'].render() %>", 'test.gsp', null) def r = this.renderer.render(specialPage, [], [part], [:]) - assertTrue(r.v1.size() == 0) + assertEmptyDiagnostics(r) assertEquals('Hello, World!', r.v2) } @Test void rendersPartWithBinding(@Mock PartRenderer partRenderer) { - when(partRenderer.render(any(), argThat { Map m -> m.get('greeting') == 'Hello, World!'}, any(), any())) - .thenReturn(new Tuple2<>([], 'Hello, World!')) + when(partRenderer.render( + any(), argThat { Map m -> m.get('greeting') == 'Hello, World!'}, any(), any(), any(), any() + )).thenReturn(new Tuple2<>([], 'Hello, World!')) def partType = new PartType([], partRenderer) def part = new Part('test', partType, '') def specialPage = new SpecialPage( "<%= parts['test'].render([greeting: 'Hello, World!'])", - null, + 'test.gsp', null ) def r = this.renderer.render(specialPage, [], [part], [:]) - assertTrue(r.v1.size() == 0) + assertEmptyDiagnostics(r) assertEquals('Hello, World!', r.v2) } @@ -67,20 +69,40 @@ class GspSpecialPageRendererTests { def specialPage = new SpecialPage( "<%= texts.find { it.path == 'test' }.render() %>", - null, + 'test.gsp', null ) def r = this.renderer.render(specialPage, [text], [], [:]) - assertTrue(r.v1.size() == 0) + assertEmptyDiagnostics(r) assertEquals('

Hello, World!

\n', r.v2) } @Test void tagBuilderAvailable() { - def specialPage = new SpecialPage('<%= tagBuilder.test() %>', null, null) + def specialPage = new SpecialPage('<%= tagBuilder.test() %>', 'test.gsp', null) def r = this.renderer.render(specialPage, [], [], [:]) - assertTrue(r.v1.isEmpty()) + assertEmptyDiagnostics(r) assertEquals('', r.v2) } + @Test + void pathAvailable() { + def specialPage = new SpecialPage('<%= path %>', 'test.gsp', null) + def r = this.renderer.render(specialPage, [], [], [:]) + assertEmptyDiagnostics(r) + assertEquals('test.gsp', r.v2) + } + + @Test + void urlBuilderAvailable() { + def specialPage = new SpecialPage( + '<%= urlBuilder.relative("images/test.jpg") %>', + 'test.gsp', + null + ) + def r = this.renderer.render(specialPage, [], [], [:]) + assertEmptyDiagnostics(r) + assertEquals('images/test.jpg', r.v2) + } + } 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 50684a7..5b301ea 100644 --- a/lib/src/test/groovy/com/jessebrault/ssg/template/GspTemplateRendererTests.groovy +++ b/lib/src/test/groovy/com/jessebrault/ssg/template/GspTemplateRendererTests.groovy @@ -3,48 +3,23 @@ package com.jessebrault.ssg.template import com.jessebrault.ssg.part.Part import com.jessebrault.ssg.part.PartRenderer import com.jessebrault.ssg.part.PartType -import com.jessebrault.ssg.text.ExcerptGetter import com.jessebrault.ssg.text.FrontMatter -import com.jessebrault.ssg.text.FrontMatterGetter -import com.jessebrault.ssg.text.Text -import com.jessebrault.ssg.text.TextRenderer -import com.jessebrault.ssg.text.TextType import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith import org.mockito.Mock import org.mockito.junit.jupiter.MockitoExtension +import static com.jessebrault.ssg.testutil.DiagnosticsUtil.getDiagnosticsMessageSupplier +import static com.jessebrault.ssg.text.TextMocks.* 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.mock import static org.mockito.Mockito.when @ExtendWith(MockitoExtension) class GspTemplateRendererTests { - /** - * TODO: move to a fixture - */ - private static Text mockBlankText() { - def textRenderer = mock(TextRenderer) - def frontMatterGetter = mock(FrontMatterGetter) - def excerptGetter = mock(ExcerptGetter) - new Text('', '', new TextType([], textRenderer, frontMatterGetter, excerptGetter)) - } - - /** - * TODO: move to a fixture - */ - private static Text mockRenderableText(String text) { - def textRenderer = mock(TextRenderer) - when(textRenderer.render(any(), any())).thenReturn(new Tuple2<>([], text)) - def frontMatterGetter = mock(FrontMatterGetter) - def excerptGetter = mock(ExcerptGetter) - new Text('', '', new TextType([], textRenderer, frontMatterGetter, excerptGetter)) - } - private final TemplateRenderer renderer = new GspTemplateRenderer() @Test @@ -55,18 +30,19 @@ class GspTemplateRendererTests { null ) - when(partRenderer.render(any(), any(), any(), any())).thenReturn(new Tuple2<>([], 'Hello, World!')) + when(partRenderer.render(any(), any(), any(), 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(null, [:]), - mockBlankText(), + blankText(), [part], [:] ) - assertTrue(r.v1.size() == 0) + assertTrue(r.v1.isEmpty(), getDiagnosticsMessageSupplier(r.v1)) assertEquals('Hello, World!', r.v2) } @@ -78,7 +54,7 @@ class GspTemplateRendererTests { null ) - when(partRenderer.render(any(), argThat { Map m -> m.get('person') == 'World' }, any(), any())) + when(partRenderer.render(any(), argThat { Map m -> m.get('person') == 'World' }, any(), any(), any(), any())) .thenReturn(new Tuple2<>([], 'Hello, World!')) def partType = new PartType([], partRenderer) def part = new Part('greeting', partType, null) @@ -86,11 +62,11 @@ class GspTemplateRendererTests { def r = this.renderer.render( template, new FrontMatter(null, [:]), - mockBlankText(), + blankText(), [part], [:] ) - assertTrue(r.v1.size() == 0) + assertTrue(r.v1.isEmpty(), getDiagnosticsMessageSupplier(r.v1)) assertEquals('Hello, World!', r.v2) } @@ -100,11 +76,11 @@ class GspTemplateRendererTests { def r = this.renderer.render( template, new FrontMatter(null, [title: ['Hello!']]), - mockBlankText(), + blankText(), [], [:] ) - assertTrue(r.v1.size() == 0) + assertTrue(r.v1.isEmpty(), getDiagnosticsMessageSupplier(r.v1)) assertEquals('Hello!', r.v2) } @@ -114,11 +90,11 @@ class GspTemplateRendererTests { def r = this.renderer.render( template, new FrontMatter(null, [:]), - mockBlankText(), + blankText(), [], [test: 'Hello, World!'] ) - assertTrue(r.v1.size() == 0) + assertTrue(r.v1.isEmpty(), getDiagnosticsMessageSupplier(r.v1)) assertEquals('Hello, World!', r.v2) } @@ -128,11 +104,11 @@ class GspTemplateRendererTests { def r = this.renderer.render( template, new FrontMatter(null, [:]), - mockRenderableText('Hello, World!'), + renderableText('Hello, World!'), [], [:] ) - assertTrue(r.v1.size() == 0) + assertTrue(r.v1.isEmpty(), getDiagnosticsMessageSupplier(r.v1)) assertEquals('Hello, World!', r.v2) } @@ -142,12 +118,40 @@ class GspTemplateRendererTests { def r = this.renderer.render( template, new FrontMatter(null, [:]), - mockBlankText(), + blankText(), [], [:] ) - assertTrue(r.v1.isEmpty()) + assertTrue(r.v1.isEmpty(), getDiagnosticsMessageSupplier(r.v1)) assertEquals('', r.v2) } + @Test + void pathAvailable() { + def template = new Template('<%= path %>', null, null) + def r = this.renderer.render( + template, + new FrontMatter(null, [:]), + textWithPath('test.md'), + [], + [:] + ) + assertTrue(r.v1.isEmpty(), getDiagnosticsMessageSupplier(r.v1)) + assertEquals('test.md', r.v2) + } + + @Test + void urlBuilderAvailable() { + def template = new Template('<%= urlBuilder.relative("images/test.jpg") %>', null, null) + def r = this.renderer.render( + template, + new FrontMatter(null, [:]), + textWithPath('test.md'), + [], + [:] + ) + assertTrue(r.v1.isEmpty(), getDiagnosticsMessageSupplier(r.v1)) + assertEquals('images/test.jpg', r.v2) + } + } diff --git a/lib/src/test/groovy/com/jessebrault/ssg/url/PathBasedUrlBuilderTests.groovy b/lib/src/test/groovy/com/jessebrault/ssg/url/PathBasedUrlBuilderTests.groovy new file mode 100644 index 0000000..4381779 --- /dev/null +++ b/lib/src/test/groovy/com/jessebrault/ssg/url/PathBasedUrlBuilderTests.groovy @@ -0,0 +1,10 @@ +package com.jessebrault.ssg.url + +class PathBasedUrlBuilderTests extends AbstractUrlBuilderTests { + + @Override + protected UrlBuilder getUrlBuilder(String fromFile) { + new PathBasedUrlBuilder(fromFile) + } + +} diff --git a/lib/src/testFixtures/groovy/com/jessebrault/ssg/testutil/DiagnosticsUtil.groovy b/lib/src/testFixtures/groovy/com/jessebrault/ssg/testutil/DiagnosticsUtil.groovy index 10d4e16..6405933 100644 --- a/lib/src/testFixtures/groovy/com/jessebrault/ssg/testutil/DiagnosticsUtil.groovy +++ b/lib/src/testFixtures/groovy/com/jessebrault/ssg/testutil/DiagnosticsUtil.groovy @@ -2,6 +2,8 @@ package com.jessebrault.ssg.testutil import com.jessebrault.ssg.Diagnostic +import static org.junit.jupiter.api.Assertions.assertTrue + class DiagnosticsUtil { static Closure getDiagnosticsMessageSupplier(Collection diagnostics) { @@ -15,4 +17,8 @@ class DiagnosticsUtil { } } + static void assertEmptyDiagnostics(Tuple2, ?> result) { + assertTrue(result.v1.isEmpty(), getDiagnosticsMessageSupplier(result.v1)) + } + } diff --git a/lib/src/testFixtures/groovy/com/jessebrault/ssg/text/TextMocks.groovy b/lib/src/testFixtures/groovy/com/jessebrault/ssg/text/TextMocks.groovy new file mode 100644 index 0000000..b27b2d1 --- /dev/null +++ b/lib/src/testFixtures/groovy/com/jessebrault/ssg/text/TextMocks.groovy @@ -0,0 +1,37 @@ +package com.jessebrault.ssg.text + +import com.jessebrault.ssg.text.ExcerptGetter +import com.jessebrault.ssg.text.FrontMatterGetter +import com.jessebrault.ssg.text.Text +import com.jessebrault.ssg.text.TextRenderer +import com.jessebrault.ssg.text.TextType + +import static org.mockito.ArgumentMatchers.any +import static org.mockito.Mockito.mock +import static org.mockito.Mockito.when + +class TextMocks { + + static Text blankText() { + def textRenderer = mock(TextRenderer) + def frontMatterGetter = mock(FrontMatterGetter) + def excerptGetter = mock(ExcerptGetter) + new Text('', '', new TextType([], textRenderer, frontMatterGetter, excerptGetter)) + } + + static Text renderableText(String text) { + def textRenderer = mock(TextRenderer) + when(textRenderer.render(any(), any())).thenReturn(new Tuple2<>([], text)) + def frontMatterGetter = mock(FrontMatterGetter) + def excerptGetter = mock(ExcerptGetter) + new Text('', '', new TextType([], textRenderer, frontMatterGetter, excerptGetter)) + } + + static Text textWithPath(String path) { + def textRenderer = mock(TextRenderer) + def frontMatterGetter = mock(FrontMatterGetter) + def excerptGetter = mock(ExcerptGetter) + new Text('', path, new TextType([], textRenderer, frontMatterGetter, excerptGetter)) + } + +} diff --git a/lib/src/testFixtures/groovy/com/jessebrault/ssg/url/AbstractUrlBuilderTests.groovy b/lib/src/testFixtures/groovy/com/jessebrault/ssg/url/AbstractUrlBuilderTests.groovy new file mode 100644 index 0000000..ebbae9b --- /dev/null +++ b/lib/src/testFixtures/groovy/com/jessebrault/ssg/url/AbstractUrlBuilderTests.groovy @@ -0,0 +1,33 @@ +package com.jessebrault.ssg.url + +import org.junit.jupiter.api.Test + +import static org.junit.jupiter.api.Assertions.assertEquals + +abstract class AbstractUrlBuilderTests { + + protected abstract UrlBuilder getUrlBuilder(String fromFile); + + @Test + void upDownDown() { + def builder = this.getUrlBuilder('posts/post.html') + assertEquals('../images/test.jpg', builder.relative('images/test.jpg')) + } + + @Test + void downDown() { + assertEquals( + 'images/test.jpg', + this.getUrlBuilder('test.html').relative('images/test.jpg') + ) + } + + @Test + void upUpDownDown() { + assertEquals( + '../../images/test.jpg', + this.getUrlBuilder('posts/old/test.html').relative('images/test.jpg') + ) + } + +}