More refactoring, added parts.
This commit is contained in:
parent
c91700aecd
commit
5b2f83898d
@ -1,31 +1,39 @@
|
||||
package com.jessebrault.ssg
|
||||
|
||||
import com.jessebrault.ssg.pagetemplate.GspRenderer
|
||||
import com.jessebrault.ssg.pagetemplate.PageTemplateType
|
||||
import com.jessebrault.ssg.pagetemplate.PageTemplatesFactoryImpl
|
||||
import com.jessebrault.ssg.part.GspPartRenderer
|
||||
import com.jessebrault.ssg.part.PartFilePartsProvider
|
||||
import com.jessebrault.ssg.part.PartType
|
||||
import com.jessebrault.ssg.template.GspTemplateRenderer
|
||||
import com.jessebrault.ssg.template.TemplateType
|
||||
import com.jessebrault.ssg.template.TemplateFileTemplatesProvider
|
||||
import com.jessebrault.ssg.text.MarkdownFrontMatterGetter
|
||||
import com.jessebrault.ssg.text.MarkdownRenderer
|
||||
import com.jessebrault.ssg.text.TextFileType
|
||||
import com.jessebrault.ssg.text.TextFilesFactoryImpl
|
||||
import com.jessebrault.ssg.text.MarkdownTextRenderer
|
||||
import com.jessebrault.ssg.text.TextType
|
||||
import com.jessebrault.ssg.text.TextFileTextsProvider
|
||||
|
||||
class StaticSiteGeneratorCli {
|
||||
|
||||
static void main(String[] args) {
|
||||
def markdown = new TextFileType(['.md'], new MarkdownRenderer(), new MarkdownFrontMatterGetter())
|
||||
def gsp = new PageTemplateType(['.gsp'], new GspRenderer())
|
||||
def markdownText = new TextType(['.md'], new MarkdownTextRenderer(), new MarkdownFrontMatterGetter())
|
||||
def gspTemplate = new TemplateType(['.gsp'], new GspTemplateRenderer())
|
||||
def gspPart = new PartType(['.gsp'], new GspPartRenderer())
|
||||
|
||||
def config = new Config(
|
||||
textFileTypes: [markdown],
|
||||
pageTemplateTypes: [gsp],
|
||||
textFileFactoryGetter: { Config config -> new TextFilesFactoryImpl(config.textFileTypes) },
|
||||
pageTemplatesFactoryGetter: { Config config -> new PageTemplatesFactoryImpl(config.pageTemplateTypes) }
|
||||
)
|
||||
def ssg = new StaticSiteGeneratorImpl(config)
|
||||
def defaultSpec = new SiteSpec(
|
||||
buildDir: new File('build'),
|
||||
textTypes: [markdownText],
|
||||
templateTypes: [gspTemplate],
|
||||
partTypes: [gspPart],
|
||||
|
||||
textsDir: new File('texts'),
|
||||
templatesDir: new File('templates')
|
||||
templatesDir: new File('templates'),
|
||||
partsDir: new File('parts'),
|
||||
|
||||
textsProviderGetter: { Config config -> new TextFileTextsProvider(config.textTypes, config.textsDir) },
|
||||
templatesProviderGetter: { Config config -> new TemplateFileTemplatesProvider(config.templateTypes, config.templatesDir) },
|
||||
partsProviderGetter: { Config config -> new PartFilePartsProvider(config.partTypes, config.partsDir) }
|
||||
)
|
||||
ssg.generate(defaultSpec)
|
||||
|
||||
def ssg = new SimpleStaticSiteGenerator(config)
|
||||
ssg.generate(new File('build'))
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,20 +1,30 @@
|
||||
package com.jessebrault.ssg
|
||||
|
||||
import com.jessebrault.ssg.pagetemplate.PageTemplateType
|
||||
import com.jessebrault.ssg.pagetemplate.PageTemplatesFactory
|
||||
import com.jessebrault.ssg.text.TextFileType
|
||||
import com.jessebrault.ssg.text.TextFilesFactory
|
||||
import com.jessebrault.ssg.part.PartType
|
||||
import com.jessebrault.ssg.part.PartsProvider
|
||||
import com.jessebrault.ssg.template.TemplateType
|
||||
import com.jessebrault.ssg.template.TemplatesProvider
|
||||
import com.jessebrault.ssg.text.TextType
|
||||
import com.jessebrault.ssg.text.TextsProvider
|
||||
import groovy.transform.Canonical
|
||||
import groovy.transform.MapConstructor
|
||||
import groovy.transform.NullCheck
|
||||
|
||||
import java.util.function.Function
|
||||
|
||||
@Canonical
|
||||
@MapConstructor
|
||||
@NullCheck
|
||||
class Config {
|
||||
Collection<TextFileType> textFileTypes
|
||||
Collection<PageTemplateType> pageTemplateTypes
|
||||
Collection<TextType> textTypes
|
||||
Collection<TemplateType> templateTypes
|
||||
Collection<PartType> partTypes
|
||||
|
||||
Function<Config, TextFilesFactory> textFileFactoryGetter
|
||||
Function<Config, PageTemplatesFactory> pageTemplatesFactoryGetter
|
||||
File textsDir
|
||||
File templatesDir
|
||||
File partsDir
|
||||
|
||||
Function<Config, TextsProvider> textsProviderGetter
|
||||
Function<Config, TemplatesProvider> templatesProviderGetter
|
||||
Function<Config, PartsProvider> partsProviderGetter
|
||||
}
|
||||
|
@ -0,0 +1,81 @@
|
||||
package com.jessebrault.ssg
|
||||
|
||||
import com.jessebrault.ssg.part.PartsProvider
|
||||
import com.jessebrault.ssg.template.TemplatesProvider
|
||||
import com.jessebrault.ssg.text.TextsProvider
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.slf4j.Marker
|
||||
import org.slf4j.MarkerFactory
|
||||
|
||||
class SimpleStaticSiteGenerator implements StaticSiteGenerator {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(SimpleStaticSiteGenerator)
|
||||
private static final Marker enter = MarkerFactory.getMarker('ENTER')
|
||||
private static final Marker exit = MarkerFactory.getMarker('EXIT')
|
||||
|
||||
private final Config config
|
||||
private final TextsProvider textsProvider
|
||||
private final TemplatesProvider templatesProvider
|
||||
private final PartsProvider partsProvider
|
||||
|
||||
SimpleStaticSiteGenerator(Config config) {
|
||||
this.config = config
|
||||
this.textsProvider = config.textsProviderGetter.apply(config)
|
||||
this.templatesProvider = config.templatesProviderGetter.apply(config)
|
||||
this.partsProvider = config.partsProviderGetter.apply(config)
|
||||
}
|
||||
|
||||
@Override
|
||||
void generate(File buildDir) {
|
||||
logger.trace(enter, 'buildDir: {}', buildDir)
|
||||
|
||||
// Get all texts, templates, and parts
|
||||
def texts = this.textsProvider.getTextFiles()
|
||||
def templates = this.templatesProvider.getTemplates()
|
||||
def parts = this.partsProvider.getParts()
|
||||
|
||||
logger.debug('texts: {}, templates: {}, parts: {}', texts, templates, parts)
|
||||
texts.each {
|
||||
logger.info('processing text: {}', it.path)
|
||||
|
||||
// Render the text (i.e., transform text to html)
|
||||
def renderedText = it.type.renderer.render(it.text)
|
||||
logger.debug('renderedText: {}', renderedText)
|
||||
|
||||
// Extract frontMatter from text
|
||||
def frontMatter = it.type.frontMatterGetter.get(it.text)
|
||||
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')
|
||||
}
|
||||
def template = templates.find {
|
||||
it.relativePath == desiredTemplate
|
||||
}
|
||||
logger.debug('template: {}', template)
|
||||
if (template == null) {
|
||||
throw new IllegalArgumentException('in textFile' + it.path + ' unknown template: ' + desiredTemplate)
|
||||
}
|
||||
|
||||
// Render the template using the result of rendering the text earlier
|
||||
def result = template.type.renderer.render(template, renderedText, parts)
|
||||
logger.debug('result: {}', result)
|
||||
|
||||
// Output the result to the outfile, an .html file
|
||||
def outFile = new File(buildDir, it.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)
|
||||
}
|
||||
logger.trace(exit, '')
|
||||
}
|
||||
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
package com.jessebrault.ssg
|
||||
|
||||
import groovy.transform.Canonical
|
||||
import groovy.transform.MapConstructor
|
||||
|
||||
@Canonical
|
||||
@MapConstructor
|
||||
class SiteSpec {
|
||||
File buildDir
|
||||
File staticDir
|
||||
File textsDir
|
||||
File templatesDir
|
||||
File templatePartsDir
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
package com.jessebrault.ssg
|
||||
|
||||
interface StaticSiteGenerator {
|
||||
void generate(SiteSpec spec)
|
||||
void generate(File buildDir)
|
||||
}
|
||||
|
@ -1,79 +0,0 @@
|
||||
package com.jessebrault.ssg
|
||||
|
||||
import com.jessebrault.ssg.pagetemplate.PageTemplatesFactory
|
||||
import com.jessebrault.ssg.text.TextFilesFactory
|
||||
import com.jessebrault.ssg.util.FileNameHandler
|
||||
import com.jessebrault.ssg.util.RelativePathHandler
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.slf4j.Marker
|
||||
import org.slf4j.MarkerFactory
|
||||
|
||||
class StaticSiteGeneratorImpl implements StaticSiteGenerator {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(StaticSiteGeneratorImpl)
|
||||
private static final Marker enter = MarkerFactory.getMarker('ENTER')
|
||||
private static final Marker exit = MarkerFactory.getMarker('EXIT')
|
||||
|
||||
private final Config config
|
||||
private final TextFilesFactory textFilesFactory
|
||||
private final PageTemplatesFactory pageTemplatesFactory
|
||||
|
||||
StaticSiteGeneratorImpl(Config config) {
|
||||
this.config = config
|
||||
this.textFilesFactory = config.textFileFactoryGetter.apply(config)
|
||||
this.pageTemplatesFactory = config.pageTemplatesFactoryGetter.apply(config)
|
||||
}
|
||||
|
||||
@Override
|
||||
void generate(SiteSpec spec) {
|
||||
logger.trace(enter, 'spec: {}', spec)
|
||||
def textFiles = this.textFilesFactory.getTextFiles(spec.textsDir)
|
||||
def pageTemplates = this.pageTemplatesFactory.getTemplates(spec.templatesDir)
|
||||
logger.debug('textFiles: {}, pageTemplates: {}', textFiles, pageTemplates)
|
||||
textFiles.each {
|
||||
logger.info('processing textFile: {}', it.relativePath)
|
||||
def fileNameHandler = new FileNameHandler(it.file)
|
||||
def textFileType = this.config.textFileTypes.find {
|
||||
it.extensions.contains(fileNameHandler.getExtension())
|
||||
}
|
||||
logger.debug('textFileType: {}', textFileType)
|
||||
if (textFileType == null) {
|
||||
throw new IllegalArgumentException('unknown textFile type: ' + it.relativePath)
|
||||
}
|
||||
|
||||
def renderedText = textFileType.renderer.render(it.file.text)
|
||||
logger.debug('renderedText: {}', renderedText)
|
||||
|
||||
def frontMatter = textFileType.frontMatterGetter.get(it.file.text)
|
||||
logger.debug('frontMatter: {}', frontMatter)
|
||||
|
||||
def desiredPageTemplate = frontMatter['template']
|
||||
logger.debug('desiredPageTemplate name: {}', desiredPageTemplate)
|
||||
if (desiredPageTemplate == null) {
|
||||
throw new IllegalArgumentException('in textFile ' + it.relativePath + ' template must not be null')
|
||||
}
|
||||
def pageTemplate = pageTemplates.find {
|
||||
it.relativePath == desiredPageTemplate
|
||||
}
|
||||
logger.debug('pageTemplate: {}', pageTemplate)
|
||||
if (pageTemplate == null) {
|
||||
throw new IllegalArgumentException('in textFile' + it.relativePath + ' unknown pageTemplate: ' + desiredPageTemplate)
|
||||
}
|
||||
|
||||
def result = pageTemplate.type.renderer.render(pageTemplate, renderedText)
|
||||
logger.debug('result: {}', result)
|
||||
|
||||
def outFile = new File(spec.buildDir, new RelativePathHandler(it.relativePath).getWithoutExtension() + '.html')
|
||||
if (outFile.exists()) {
|
||||
logger.info('outFile {} already exists, deleting', outFile)
|
||||
outFile.delete()
|
||||
}
|
||||
outFile.createParentDirectories()
|
||||
logger.info('writing result to {}', outFile)
|
||||
outFile.write(result)
|
||||
}
|
||||
logger.trace(exit, '')
|
||||
}
|
||||
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package com.jessebrault.ssg.pagetemplate
|
||||
|
||||
|
||||
import groovy.text.GStringTemplateEngine
|
||||
import groovy.text.TemplateEngine
|
||||
|
||||
class GspRenderer implements PageRenderer {
|
||||
|
||||
private static final TemplateEngine engine = new GStringTemplateEngine()
|
||||
|
||||
@Override
|
||||
String render(PageTemplate template, String text) {
|
||||
engine.createTemplate(template.file.text).make([
|
||||
text: text
|
||||
])
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package com.jessebrault.ssg.pagetemplate
|
||||
|
||||
interface PageRenderer {
|
||||
String render(PageTemplate template, String text)
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
package com.jessebrault.ssg.pagetemplate
|
||||
|
||||
import groovy.transform.Canonical
|
||||
|
||||
@Canonical
|
||||
class PageTemplate {
|
||||
File file
|
||||
String relativePath
|
||||
PageTemplateType type
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
package com.jessebrault.ssg.pagetemplate
|
||||
|
||||
import groovy.transform.Canonical
|
||||
|
||||
@Canonical
|
||||
class PageTemplateType {
|
||||
Collection<String> extensions
|
||||
PageRenderer renderer
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package com.jessebrault.ssg.pagetemplate
|
||||
|
||||
interface PageTemplatesFactory {
|
||||
Collection<PageTemplate> getTemplates(File templatesDir)
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.jessebrault.ssg.part
|
||||
|
||||
import groovy.text.GStringTemplateEngine
|
||||
import groovy.text.TemplateEngine
|
||||
|
||||
class GspPartRenderer implements PartRenderer {
|
||||
|
||||
private static final TemplateEngine engine = new GStringTemplateEngine()
|
||||
|
||||
@Override
|
||||
String render(String partText, Map binding) {
|
||||
engine.createTemplate(partText).make(binding)
|
||||
}
|
||||
|
||||
}
|
14
lib/src/main/groovy/com/jessebrault/ssg/part/Part.groovy
Normal file
14
lib/src/main/groovy/com/jessebrault/ssg/part/Part.groovy
Normal file
@ -0,0 +1,14 @@
|
||||
package com.jessebrault.ssg.part
|
||||
|
||||
import groovy.transform.Canonical
|
||||
import groovy.transform.NullCheck
|
||||
import groovy.transform.TupleConstructor
|
||||
|
||||
@Canonical
|
||||
@TupleConstructor(defaults = false)
|
||||
@NullCheck
|
||||
class Part {
|
||||
String name
|
||||
PartType type
|
||||
String text
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package com.jessebrault.ssg.part
|
||||
|
||||
import com.jessebrault.ssg.util.FileNameHandler
|
||||
import groovy.transform.NullCheck
|
||||
import groovy.transform.TupleConstructor
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
@TupleConstructor(includeFields = true, defaults = false)
|
||||
@NullCheck
|
||||
class PartFilePartsProvider implements PartsProvider {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(PartFilePartsProvider)
|
||||
|
||||
private final Collection<PartType> partTypes
|
||||
private final File partsDir
|
||||
|
||||
private PartType getPartType(File file) {
|
||||
partTypes.find {
|
||||
it.extensions.contains(new FileNameHandler(file).getExtension())
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
Collection<Part> getParts() {
|
||||
if (!partsDir.isDirectory()) {
|
||||
throw new IllegalArgumentException('partsDir must be a directory')
|
||||
}
|
||||
|
||||
def parts = []
|
||||
partsDir.eachFileRecurse {
|
||||
if (it.isFile()) {
|
||||
def type = this.getPartType(it)
|
||||
if (type != null) {
|
||||
def relativePath = this.partsDir.relativePath(it)
|
||||
logger.debug('found part {}', relativePath)
|
||||
parts << new Part(relativePath, type, it.text)
|
||||
}
|
||||
}
|
||||
}
|
||||
parts
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package com.jessebrault.ssg.part
|
||||
|
||||
interface PartRenderer {
|
||||
String render(String partText, Map binding)
|
||||
}
|
13
lib/src/main/groovy/com/jessebrault/ssg/part/PartType.groovy
Normal file
13
lib/src/main/groovy/com/jessebrault/ssg/part/PartType.groovy
Normal file
@ -0,0 +1,13 @@
|
||||
package com.jessebrault.ssg.part
|
||||
|
||||
import groovy.transform.Canonical
|
||||
import groovy.transform.NullCheck
|
||||
import groovy.transform.TupleConstructor
|
||||
|
||||
@Canonical
|
||||
@TupleConstructor(defaults = false)
|
||||
@NullCheck
|
||||
class PartType {
|
||||
Collection<String> extensions
|
||||
PartRenderer renderer
|
||||
}
|
35
lib/src/main/groovy/com/jessebrault/ssg/part/PartsMap.groovy
Normal file
35
lib/src/main/groovy/com/jessebrault/ssg/part/PartsMap.groovy
Normal file
@ -0,0 +1,35 @@
|
||||
package com.jessebrault.ssg.part
|
||||
|
||||
import groovy.transform.TupleConstructor
|
||||
|
||||
class PartsMap {
|
||||
|
||||
@TupleConstructor(includeFields = true, defaults = false)
|
||||
class RenderingPart {
|
||||
|
||||
private final Part part
|
||||
|
||||
String render(Map binding) {
|
||||
part.type.renderer.render(part.text, binding)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final Map<String, RenderingPart> partsMap = new LinkedHashMap<>()
|
||||
|
||||
PartsMap(Collection<Part> parts) {
|
||||
Objects.requireNonNull(parts)
|
||||
parts.each {
|
||||
this.partsMap.put(it.name, new RenderingPart(it))
|
||||
}
|
||||
}
|
||||
|
||||
RenderingPart get(String name) {
|
||||
this.partsMap.get(Objects.requireNonNull(name))
|
||||
}
|
||||
|
||||
RenderingPart getAt(String name) {
|
||||
this.get(Objects.requireNonNull(name))
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package com.jessebrault.ssg.part
|
||||
|
||||
interface PartsProvider {
|
||||
Collection<Part> getParts()
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package com.jessebrault.ssg.template
|
||||
|
||||
import com.jessebrault.ssg.part.Part
|
||||
import com.jessebrault.ssg.part.PartsMap
|
||||
import groovy.text.GStringTemplateEngine
|
||||
import groovy.text.TemplateEngine
|
||||
|
||||
class GspTemplateRenderer implements TemplateRenderer {
|
||||
|
||||
private static final TemplateEngine engine = new GStringTemplateEngine()
|
||||
|
||||
@Override
|
||||
String render(Template template, String text, Collection<Part> parts) {
|
||||
engine.createTemplate(template.text).make([
|
||||
text: text,
|
||||
parts: new PartsMap(parts)
|
||||
])
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package com.jessebrault.ssg.template
|
||||
|
||||
import groovy.transform.Canonical
|
||||
import groovy.transform.NullCheck
|
||||
import groovy.transform.TupleConstructor
|
||||
|
||||
@Canonical
|
||||
@TupleConstructor(defaults = false)
|
||||
@NullCheck
|
||||
class Template {
|
||||
String text
|
||||
String relativePath
|
||||
TemplateType type
|
||||
}
|
@ -1,36 +1,39 @@
|
||||
package com.jessebrault.ssg.pagetemplate
|
||||
package com.jessebrault.ssg.template
|
||||
|
||||
import com.jessebrault.ssg.util.FileNameHandler
|
||||
import groovy.transform.NullCheck
|
||||
import groovy.transform.TupleConstructor
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
@TupleConstructor(includeFields = true)
|
||||
class PageTemplatesFactoryImpl implements PageTemplatesFactory {
|
||||
@TupleConstructor(includeFields = true, defaults = false)
|
||||
@NullCheck
|
||||
class TemplateFileTemplatesProvider implements TemplatesProvider {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(PageTemplatesFactoryImpl)
|
||||
private static final Logger logger = LoggerFactory.getLogger(TemplateFileTemplatesProvider)
|
||||
|
||||
private final Collection<PageTemplateType> types
|
||||
private final Collection<TemplateType> types
|
||||
private final File templatesDir
|
||||
|
||||
private PageTemplateType getType(File file) {
|
||||
private TemplateType getType(File file) {
|
||||
this.types.find {
|
||||
it.extensions.contains(new FileNameHandler(file).getExtension())
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
Collection<PageTemplate> getTemplates(File templatesDir) {
|
||||
if (!templatesDir.isDirectory()) {
|
||||
Collection<Template> getTemplates() {
|
||||
if (!this.templatesDir.isDirectory()) {
|
||||
throw new IllegalArgumentException('templatesDir must be a directory')
|
||||
}
|
||||
def templates = []
|
||||
templatesDir.eachFileRecurse {
|
||||
this.templatesDir.eachFileRecurse {
|
||||
if (it.isFile()) {
|
||||
def type = this.getType(it)
|
||||
if (type != null) {
|
||||
def relativePath = templatesDir.relativePath(it)
|
||||
def relativePath = this.templatesDir.relativePath(it)
|
||||
logger.debug('found template {}', relativePath)
|
||||
templates << new PageTemplate(it, relativePath, type)
|
||||
templates << new Template(it.text, relativePath, type)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package com.jessebrault.ssg.template
|
||||
|
||||
import com.jessebrault.ssg.part.Part
|
||||
|
||||
interface TemplateRenderer {
|
||||
String render(Template template, String text, Collection<Part> parts)
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.jessebrault.ssg.template
|
||||
|
||||
import groovy.transform.Canonical
|
||||
import groovy.transform.NullCheck
|
||||
import groovy.transform.TupleConstructor
|
||||
|
||||
@Canonical
|
||||
@TupleConstructor(defaults = false)
|
||||
@NullCheck
|
||||
class TemplateType {
|
||||
Collection<String> extensions
|
||||
TemplateRenderer renderer
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package com.jessebrault.ssg.template
|
||||
|
||||
interface TemplatesProvider {
|
||||
Collection<Template> getTemplates()
|
||||
}
|
@ -1,9 +1,11 @@
|
||||
package com.jessebrault.ssg.text
|
||||
|
||||
import groovy.transform.NullCheck
|
||||
import groovy.transform.ToString
|
||||
import groovy.transform.TupleConstructor
|
||||
|
||||
@TupleConstructor(includeFields = true)
|
||||
@TupleConstructor(includeFields = true, defaults = false)
|
||||
@NullCheck
|
||||
@ToString
|
||||
class FrontMatter {
|
||||
|
||||
|
@ -0,0 +1,5 @@
|
||||
package com.jessebrault.ssg.text
|
||||
|
||||
interface FrontMatterGetter {
|
||||
FrontMatter get(String text)
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package com.jessebrault.ssg.text;
|
||||
|
||||
public interface FrontMatterGetter {
|
||||
FrontMatter get(String text);
|
||||
}
|
@ -4,7 +4,7 @@ import org.commonmark.ext.front.matter.YamlFrontMatterExtension
|
||||
import org.commonmark.parser.Parser
|
||||
import org.commonmark.renderer.html.HtmlRenderer
|
||||
|
||||
class MarkdownRenderer implements TextRenderer {
|
||||
class MarkdownTextRenderer implements TextRenderer {
|
||||
|
||||
private static final Parser parser = Parser.builder()
|
||||
.extensions([YamlFrontMatterExtension.create()])
|
14
lib/src/main/groovy/com/jessebrault/ssg/text/Text.groovy
Normal file
14
lib/src/main/groovy/com/jessebrault/ssg/text/Text.groovy
Normal file
@ -0,0 +1,14 @@
|
||||
package com.jessebrault.ssg.text
|
||||
|
||||
import groovy.transform.Canonical
|
||||
import groovy.transform.NullCheck
|
||||
import groovy.transform.TupleConstructor
|
||||
|
||||
@Canonical
|
||||
@TupleConstructor(defaults = false)
|
||||
@NullCheck
|
||||
class Text {
|
||||
String text
|
||||
String path
|
||||
TextType type
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
package com.jessebrault.ssg.text
|
||||
|
||||
import groovy.transform.Canonical
|
||||
|
||||
@Canonical
|
||||
class TextFile {
|
||||
File file
|
||||
String relativePath
|
||||
TextFileType type
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package com.jessebrault.ssg.text
|
||||
|
||||
import com.jessebrault.ssg.util.FileNameHandler
|
||||
import com.jessebrault.ssg.util.RelativePathHandler
|
||||
import groovy.transform.NullCheck
|
||||
import groovy.transform.TupleConstructor
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
@TupleConstructor(includeFields = true, defaults = false)
|
||||
@NullCheck
|
||||
class TextFileTextsProvider implements TextsProvider {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(TextFileTextsProvider)
|
||||
|
||||
private final Collection<TextType> textTypes
|
||||
private final File textsDir
|
||||
|
||||
private TextType getTextType(File file) {
|
||||
this.textTypes.find {
|
||||
it.ids.contains(new FileNameHandler(file).getExtension())
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
Collection<Text> getTextFiles() {
|
||||
if (!this.textsDir.isDirectory()) {
|
||||
throw new IllegalArgumentException('textsDir must be a directory')
|
||||
}
|
||||
|
||||
def textFiles = []
|
||||
this.textsDir.eachFileRecurse {
|
||||
if (it.isFile()) {
|
||||
def type = this.getTextType(it)
|
||||
if (type != null) {
|
||||
def relativePath = this.textsDir.relativePath(it)
|
||||
def path = new RelativePathHandler(relativePath).getWithoutExtension()
|
||||
logger.debug('found textFile {} with type {}', path, type)
|
||||
textFiles << new Text(it.text, path, type)
|
||||
}
|
||||
}
|
||||
}
|
||||
textFiles
|
||||
}
|
||||
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
package com.jessebrault.ssg.text
|
||||
|
||||
import groovy.transform.Canonical
|
||||
|
||||
@Canonical
|
||||
class TextFileType {
|
||||
Collection<String> extensions
|
||||
TextRenderer renderer
|
||||
FrontMatterGetter frontMatterGetter
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package com.jessebrault.ssg.text
|
||||
|
||||
interface TextFilesFactory {
|
||||
Collection<TextFile> getTextFiles(File textsDir)
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
package com.jessebrault.ssg.text
|
||||
|
||||
import com.jessebrault.ssg.util.FileNameHandler
|
||||
import groovy.transform.TupleConstructor
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
@TupleConstructor(includeFields = true)
|
||||
class TextFilesFactoryImpl implements TextFilesFactory {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(TextFilesFactoryImpl)
|
||||
|
||||
private final Collection<TextFileType> textFileTypes
|
||||
|
||||
private TextFileType getTextFileType(File file) {
|
||||
textFileTypes.find {
|
||||
it.extensions.contains(new FileNameHandler(file).getExtension())
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
Collection<TextFile> getTextFiles(File textsDir) {
|
||||
if (!textsDir.isDirectory()) {
|
||||
throw new IllegalArgumentException('textsDir must be a directory')
|
||||
}
|
||||
|
||||
def textFiles = []
|
||||
textsDir.eachFileRecurse {
|
||||
if (it.isFile()) {
|
||||
def type = this.getTextFileType(it)
|
||||
if (type != null) {
|
||||
def relativePath = textsDir.relativePath(it)
|
||||
logger.debug('found textFile {}', relativePath)
|
||||
textFiles << new TextFile(it, relativePath, type)
|
||||
}
|
||||
}
|
||||
}
|
||||
textFiles
|
||||
}
|
||||
|
||||
}
|
14
lib/src/main/groovy/com/jessebrault/ssg/text/TextType.groovy
Normal file
14
lib/src/main/groovy/com/jessebrault/ssg/text/TextType.groovy
Normal file
@ -0,0 +1,14 @@
|
||||
package com.jessebrault.ssg.text
|
||||
|
||||
import groovy.transform.Canonical
|
||||
import groovy.transform.NullCheck
|
||||
import groovy.transform.TupleConstructor
|
||||
|
||||
@Canonical
|
||||
@TupleConstructor(defaults = false)
|
||||
@NullCheck
|
||||
class TextType {
|
||||
Collection<String> ids
|
||||
TextRenderer renderer
|
||||
FrontMatterGetter frontMatterGetter
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package com.jessebrault.ssg.text
|
||||
|
||||
interface TextsProvider {
|
||||
Collection<Text> getTextFiles()
|
||||
}
|
@ -1,8 +1,10 @@
|
||||
package com.jessebrault.ssg.util
|
||||
|
||||
import groovy.transform.NullCheck
|
||||
import groovy.transform.TupleConstructor
|
||||
|
||||
@TupleConstructor(includeFields = true)
|
||||
@TupleConstructor(includeFields = true, defaults = false)
|
||||
@NullCheck
|
||||
class FileNameHandler {
|
||||
|
||||
private final File file
|
||||
@ -11,4 +13,8 @@ class FileNameHandler {
|
||||
this.file.name.substring(this.file.name.lastIndexOf('.'))
|
||||
}
|
||||
|
||||
String getWithoutExtension() {
|
||||
this.file.name.substring(0, this.file.name.lastIndexOf('.'))
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
package com.jessebrault.ssg.util
|
||||
|
||||
import groovy.transform.NullCheck
|
||||
import groovy.transform.TupleConstructor
|
||||
|
||||
@TupleConstructor(includeFields = true)
|
||||
@TupleConstructor(includeFields = true, defaults = false)
|
||||
@NullCheck
|
||||
class RelativePathHandler {
|
||||
|
||||
private final String relativePath
|
||||
|
@ -1,44 +1,58 @@
|
||||
package com.jessebrault.ssg
|
||||
|
||||
import com.jessebrault.ssg.pagetemplate.GspRenderer
|
||||
import com.jessebrault.ssg.pagetemplate.PageTemplateType
|
||||
import com.jessebrault.ssg.pagetemplate.PageTemplatesFactoryImpl
|
||||
import com.jessebrault.ssg.part.GspPartRenderer
|
||||
import com.jessebrault.ssg.part.PartFilePartsProvider
|
||||
import com.jessebrault.ssg.part.PartType
|
||||
import com.jessebrault.ssg.template.GspTemplateRenderer
|
||||
import com.jessebrault.ssg.template.TemplateType
|
||||
import com.jessebrault.ssg.template.TemplateFileTemplatesProvider
|
||||
import com.jessebrault.ssg.text.MarkdownFrontMatterGetter
|
||||
import com.jessebrault.ssg.text.MarkdownRenderer
|
||||
import com.jessebrault.ssg.text.TextFileType
|
||||
import com.jessebrault.ssg.text.TextFilesFactoryImpl
|
||||
import com.jessebrault.ssg.text.MarkdownTextRenderer
|
||||
import com.jessebrault.ssg.text.TextType
|
||||
import com.jessebrault.ssg.text.TextFileTextsProvider
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue
|
||||
|
||||
class StaticSiteGeneratorTests {
|
||||
|
||||
private final StaticSiteGenerator ssg = new StaticSiteGeneratorImpl(new Config(
|
||||
textFileTypes: [new TextFileType(['.md'], new MarkdownRenderer(), new MarkdownFrontMatterGetter())],
|
||||
pageTemplateTypes: [new PageTemplateType(['.gsp'], new GspRenderer())],
|
||||
textFileFactoryGetter: { Config config -> new TextFilesFactoryImpl(config.textFileTypes) },
|
||||
pageTemplatesFactoryGetter: { Config config -> new PageTemplatesFactoryImpl(config.pageTemplateTypes) }
|
||||
))
|
||||
private File partsDir
|
||||
private File templatesDir
|
||||
private File textsDir
|
||||
|
||||
private StaticSiteGenerator ssg
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
this.textsDir = File.createTempDir()
|
||||
this.templatesDir = File.createTempDir()
|
||||
this.partsDir = File.createTempDir()
|
||||
|
||||
def config = new Config(
|
||||
textTypes: [new TextType(['.md'], new MarkdownTextRenderer(), new MarkdownFrontMatterGetter())],
|
||||
templateTypes: [new TemplateType(['.gsp'], new GspTemplateRenderer())],
|
||||
partTypes: [new PartType(['.gsp'], new GspPartRenderer())],
|
||||
|
||||
textsDir: this.textsDir,
|
||||
templatesDir: this.templatesDir,
|
||||
partsDir: this.partsDir,
|
||||
|
||||
textsProviderGetter: { Config config -> new TextFileTextsProvider(config.textTypes, config.textsDir) },
|
||||
templatesProviderGetter: { Config config -> new TemplateFileTemplatesProvider(config.templateTypes, config.templatesDir) },
|
||||
partsProviderGetter: { Config config -> new PartFilePartsProvider(config.partTypes, config.partsDir) }
|
||||
)
|
||||
this.ssg = new SimpleStaticSiteGenerator(config)
|
||||
}
|
||||
|
||||
@Test
|
||||
void simple() {
|
||||
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()
|
||||
def textsDir = File.createTempDir()
|
||||
def templatesDir = File.createTempDir()
|
||||
|
||||
new File(textsDir, 'test.md').write('---\ntemplate: test.gsp\n---\n**Hello, World!**')
|
||||
new File(templatesDir, 'test.gsp').write('<%= text %>')
|
||||
|
||||
def spec = new SiteSpec(
|
||||
buildDir: buildDir,
|
||||
textsDir: textsDir,
|
||||
templatesDir: templatesDir
|
||||
)
|
||||
|
||||
this.ssg.generate(spec)
|
||||
this.ssg.generate(buildDir)
|
||||
|
||||
def outFile = new File(buildDir, 'test.html')
|
||||
assertTrue(outFile.exists())
|
||||
@ -47,23 +61,16 @@ class StaticSiteGeneratorTests {
|
||||
|
||||
@Test
|
||||
void nested() {
|
||||
def buildDir = File.createTempDir()
|
||||
def textsDir = File.createTempDir()
|
||||
def templatesDir = File.createTempDir()
|
||||
|
||||
new FileTreeBuilder(textsDir).with {
|
||||
new FileTreeBuilder(this.textsDir).with {
|
||||
dir('nested') {
|
||||
file('nested.md', '---\ntemplate: nested.gsp\n---\n**Hello, World!**')
|
||||
}
|
||||
}
|
||||
|
||||
new File(templatesDir, 'nested.gsp').write('<%= text %>')
|
||||
new File(this.templatesDir, 'nested.gsp').write('<%= text %>')
|
||||
|
||||
this.ssg.generate(new SiteSpec(
|
||||
buildDir: buildDir,
|
||||
textsDir: textsDir,
|
||||
templatesDir: templatesDir
|
||||
))
|
||||
def buildDir = File.createTempDir()
|
||||
this.ssg.generate(buildDir)
|
||||
|
||||
def outFile = new File(new File(buildDir, 'nested'), 'nested.html')
|
||||
assertTrue(outFile.exists())
|
||||
|
@ -1,55 +0,0 @@
|
||||
package com.jessebrault.ssg.pagetemplate
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals
|
||||
|
||||
class PageTemplatesFactoryTests {
|
||||
|
||||
private static final PageTemplateType gspType = new PageTemplateType(['.gsp'], null)
|
||||
|
||||
private final PageTemplatesFactory templateFactory = new PageTemplatesFactoryImpl([gspType])
|
||||
|
||||
@Test
|
||||
void findsTemplate() {
|
||||
def templatesDir = File.createTempDir()
|
||||
def templateFile = new File(templatesDir, 'test.gsp')
|
||||
templateFile.write('<% out << text %>')
|
||||
|
||||
def r = this.templateFactory.getTemplates(templatesDir)
|
||||
assertEquals(1, r.size())
|
||||
def t0 = r[0]
|
||||
assertEquals('test.gsp', t0.relativePath)
|
||||
assertEquals('<% out << text %>', t0.file.text)
|
||||
assertEquals(gspType, t0.type)
|
||||
}
|
||||
|
||||
@Test
|
||||
void findsNestedTemplate() {
|
||||
def templatesDir = File.createTempDir()
|
||||
new FileTreeBuilder(templatesDir).with {
|
||||
dir('nested') {
|
||||
file('nested.gsp', '<%= text %>')
|
||||
}
|
||||
}
|
||||
|
||||
def r = this.templateFactory.getTemplates(templatesDir)
|
||||
assertEquals(1, r.size())
|
||||
def t0 = r[0]
|
||||
assertEquals('nested/nested.gsp', t0.relativePath)
|
||||
assertEquals('<%= text %>', t0.file.text)
|
||||
assertEquals(gspType, t0.type)
|
||||
}
|
||||
|
||||
@Test
|
||||
void ignoresUnsupportedFile() {
|
||||
def templatesDir = File.createTempDir()
|
||||
new File(templatesDir, '.ignored').with {
|
||||
write('Ignored!')
|
||||
}
|
||||
|
||||
def r = this.templateFactory.getTemplates(templatesDir)
|
||||
assertEquals(0, r.size())
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package com.jessebrault.ssg.part
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals
|
||||
|
||||
class PartFilePartsProviderTests {
|
||||
|
||||
private static final PartType gspPartType = new PartType(['.gsp'], null)
|
||||
|
||||
private File partsDir
|
||||
private PartsProvider partsProvider
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
this.partsDir = File.createTempDir()
|
||||
partsProvider = new PartFilePartsProvider([gspPartType], this.partsDir)
|
||||
}
|
||||
|
||||
@Test
|
||||
void findsPart() {
|
||||
new FileTreeBuilder(this.partsDir).file('testPart.gsp') {
|
||||
write('Hello <%= name %>!')
|
||||
}
|
||||
|
||||
def r = this.partsProvider.getParts()
|
||||
assertEquals(1, r.size())
|
||||
def p0 = r[0]
|
||||
assertEquals('testPart.gsp', p0.name)
|
||||
assertEquals(gspPartType, p0.type)
|
||||
assertEquals('Hello <%= name %>!', p0.text)
|
||||
}
|
||||
|
||||
@Test
|
||||
void findsNested() {
|
||||
new FileTreeBuilder(this.partsDir).dir('nested') {
|
||||
file('testPart.gsp') {
|
||||
write('Hello, World!')
|
||||
}
|
||||
}
|
||||
|
||||
def r = this.partsProvider.getParts()
|
||||
assertEquals(1, r.size())
|
||||
def p0 = r[0]
|
||||
assertEquals('nested/testPart.gsp', p0.name)
|
||||
assertEquals(gspPartType, p0.type)
|
||||
assertEquals('Hello, World!', p0.text)
|
||||
}
|
||||
|
||||
@Test
|
||||
void ignoresUnsupportedFile() {
|
||||
new FileTreeBuilder(this.partsDir).file('.ignored') {
|
||||
write 'Ignored!'
|
||||
}
|
||||
|
||||
def r = this.partsProvider.getParts()
|
||||
assertEquals(0, r.size())
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.jessebrault.ssg.template
|
||||
|
||||
import com.jessebrault.ssg.part.GspPartRenderer
|
||||
import com.jessebrault.ssg.part.Part
|
||||
import com.jessebrault.ssg.part.PartType
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals
|
||||
|
||||
class GspTemplateRendererTests {
|
||||
|
||||
private final TemplateRenderer renderer = new GspTemplateRenderer()
|
||||
|
||||
@Test
|
||||
void rendersPart() {
|
||||
def template = new Template(
|
||||
"<%= parts['greeting'].render([person: 'World']) %>",
|
||||
null,
|
||||
null
|
||||
)
|
||||
def part = new Part(
|
||||
'greeting',
|
||||
new PartType(['.gsp'], new GspPartRenderer()),
|
||||
'Hello, $person!'
|
||||
)
|
||||
def r = this.renderer.render(template, '', [part])
|
||||
assertEquals('Hello, World!', r)
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package com.jessebrault.ssg.template
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals
|
||||
|
||||
class PageTemplatesProviderTests {
|
||||
|
||||
private static final TemplateType gspType = new TemplateType(['.gsp'], null)
|
||||
|
||||
private File templatesDir
|
||||
private TemplatesProvider templatesProvider
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
this.templatesDir = File.createTempDir()
|
||||
this.templatesProvider = new TemplateFileTemplatesProvider([gspType], this.templatesDir)
|
||||
}
|
||||
|
||||
@Test
|
||||
void findsTemplate() {
|
||||
new File(this.templatesDir, 'test.gsp').write('<% out << text %>')
|
||||
|
||||
def r = this.templatesProvider.getTemplates()
|
||||
assertEquals(1, r.size())
|
||||
def t0 = r[0]
|
||||
assertEquals('test.gsp', t0.relativePath)
|
||||
assertEquals('<% out << text %>', t0.text)
|
||||
assertEquals(gspType, t0.type)
|
||||
}
|
||||
|
||||
@Test
|
||||
void findsNestedTemplate() {
|
||||
new FileTreeBuilder(this.templatesDir).with {
|
||||
dir('nested') {
|
||||
file('nested.gsp', '<%= text %>')
|
||||
}
|
||||
}
|
||||
|
||||
def r = this.templatesProvider.getTemplates()
|
||||
assertEquals(1, r.size())
|
||||
def t0 = r[0]
|
||||
assertEquals('nested/nested.gsp', t0.relativePath)
|
||||
assertEquals('<%= text %>', t0.text)
|
||||
assertEquals(gspType, t0.type)
|
||||
}
|
||||
|
||||
@Test
|
||||
void ignoresUnsupportedFile() {
|
||||
new File(this.templatesDir, '.ignored').with {
|
||||
write('Ignored!')
|
||||
}
|
||||
|
||||
def r = this.templatesProvider.getTemplates()
|
||||
assertEquals(0, r.size())
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
package com.jessebrault.ssg.text
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals
|
||||
|
||||
class TextFileTextsProviderTests {
|
||||
|
||||
private static final TextType markdownType = new TextType(['.md'], null, null)
|
||||
|
||||
private File textsDir
|
||||
private TextsProvider textsProvider
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
this.textsDir = File.createTempDir()
|
||||
this.textsProvider = new TextFileTextsProvider([markdownType], this.textsDir)
|
||||
}
|
||||
|
||||
@Test
|
||||
void findsFile() {
|
||||
new FileTreeBuilder(this.textsDir).file('test.md', '**Hello, World!**')
|
||||
|
||||
def r = textsProvider.getTextFiles()
|
||||
assertEquals(1, r.size())
|
||||
def f0 = r[0]
|
||||
assertEquals('test', f0.path)
|
||||
assertEquals('**Hello, World!**', f0.text)
|
||||
assertEquals(markdownType, f0.type)
|
||||
}
|
||||
|
||||
@Test
|
||||
void findsNestedFiles() {
|
||||
new FileTreeBuilder(this.textsDir).dir('nested') {
|
||||
file('nested.md', '**Hello!**')
|
||||
}
|
||||
|
||||
def r = textsProvider.getTextFiles()
|
||||
assertEquals(1, r.size())
|
||||
def f0 = r[0]
|
||||
assertEquals('nested/nested', f0.path)
|
||||
assertEquals('**Hello!**', f0.text)
|
||||
assertEquals(markdownType, f0.type)
|
||||
}
|
||||
|
||||
@Test
|
||||
void ignoresUnsupportedFile() {
|
||||
new FileTreeBuilder(this.textsDir).file('.ignored', 'Ignored!')
|
||||
|
||||
def r = textsProvider.getTextFiles()
|
||||
assertEquals(0, r.size())
|
||||
}
|
||||
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
package com.jessebrault.ssg.text
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals
|
||||
|
||||
class TextsFilesFactoryTests {
|
||||
|
||||
private static final TextFileType markdownType = new TextFileType(['.md'], null, null)
|
||||
|
||||
private final TextFilesFactory textFilesFactory = new TextFilesFactoryImpl([markdownType])
|
||||
|
||||
@Test
|
||||
void findsFile() {
|
||||
def baseDir = File.createTempDir()
|
||||
def ftb = new FileTreeBuilder(baseDir)
|
||||
ftb.file('test.md', '**Hello, World!**')
|
||||
|
||||
def r = textFilesFactory.getTextFiles(baseDir)
|
||||
assertEquals(1, r.size())
|
||||
def f0 = r[0]
|
||||
assertEquals('test.md', f0.relativePath)
|
||||
assertEquals('**Hello, World!**', f0.file.text)
|
||||
assertEquals(markdownType, f0.type)
|
||||
}
|
||||
|
||||
@Test
|
||||
void findsNestedFiles() {
|
||||
def baseDir = File.createTempDir()
|
||||
def ftb = new FileTreeBuilder(baseDir)
|
||||
ftb.dir('nested') {
|
||||
file('nested.md', '**Hello!**')
|
||||
}
|
||||
|
||||
def r = textFilesFactory.getTextFiles(baseDir)
|
||||
assertEquals(1, r.size())
|
||||
def f0 = r[0]
|
||||
assertEquals('nested/nested.md', f0.relativePath)
|
||||
assertEquals('**Hello!**', f0.file.text)
|
||||
assertEquals(markdownType, f0.type)
|
||||
}
|
||||
|
||||
@Test
|
||||
void ignoresUnsupportedFile() {
|
||||
def baseDir = File.createTempDir()
|
||||
def ftb = new FileTreeBuilder(baseDir)
|
||||
ftb.file('.ignored', 'Ignored!')
|
||||
|
||||
def r = textFilesFactory.getTextFiles(baseDir)
|
||||
assertEquals(0, r.size())
|
||||
}
|
||||
|
||||
}
|
@ -6,8 +6,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals
|
||||
|
||||
class FileNameHandlerTests {
|
||||
|
||||
private final FileNameHandler fileNameHandler = new FileNameHandler()
|
||||
|
||||
@Test
|
||||
void getsCorrectExtension() {
|
||||
def file = new File('hello.txt')
|
||||
|
Loading…
Reference in New Issue
Block a user