Beginning to move logic from Runner to util methods in BuildScripts.

This commit is contained in:
JesseBrault0709 2023-05-14 15:44:07 +02:00
parent 450e5ca428
commit cdda27ea3a
4 changed files with 273 additions and 183 deletions

View File

@ -5,6 +5,9 @@ import groovy.transform.stc.SimpleType
import java.util.function.Consumer
/**
* TODO: get rid of this, split it into two different classes/util functions (BuildScripts?)
*/
interface BuildScriptRunner {
Collection<Build> runBuildScript(

View File

@ -0,0 +1,79 @@
package com.jessebrault.ssg.buildscript
import groovy.transform.stc.ClosureParams
import groovy.transform.stc.SimpleType
import org.codehaus.groovy.control.CompilerConfiguration
import java.util.function.Consumer
final class BuildScripts {
private static Collection<Build> runBase(BuildScriptBase base) {
base.run()
BuildSpecUtil.getBuilds(base.getBuildSpecs())
}
static Collection<Build> runBuildScript(
@DelegatesTo(value = BuildScriptBase, strategy = Closure.DELEGATE_FIRST)
@ClosureParams(value = SimpleType, options = 'com.jessebrault.ssg.buildscript.BuildScriptBase')
Closure<?> scriptBody
) {
def base = new BuildScriptBase() {
@Override
Object run() {
scriptBody.delegate = this
scriptBody.resolveStrategy = Closure.DELEGATE_FIRST
scriptBody.call(this)
}
}
runBase(base)
}
static Collection<Build> runBuildScript(
String scriptName,
URL scriptBaseDirUrl,
Collection<URL> otherUrls,
Map<String, Object> binding,
Consumer<BuildScriptBase> configureBuildScript
) {
def engine = new GroovyScriptEngine([scriptBaseDirUrl, *otherUrls] as URL[])
engine.config = new CompilerConfiguration().tap {
scriptBaseClass = 'com.jessebrault.ssg.buildscript.BuildScriptBase'
}
def base = engine.createScript(scriptName, new Binding(binding))
assert base instanceof BuildScriptBase
configureBuildScript.accept(base)
runBase(base)
}
static Collection<Build> runBuildScript(
String scriptName,
URL scriptBaseDirUrl,
Collection<URL> otherUrls,
Map<String, Object> binding
) {
runBuildScript(scriptName, scriptBaseDirUrl, otherUrls, binding) { }
}
static Collection<Build> runBuildScript(
String scriptName,
URL scriptBaseDirUrl,
Collection<URL> otherUrls
) {
runBuildScript(scriptName, scriptBaseDirUrl, otherUrls, [:]) { }
}
static Collection<Build> runBuildScript(
String scriptName,
URL scriptBaseDirUrl
) {
runBuildScript(scriptName, scriptBaseDirUrl, [], [:]) { }
}
private BuildScripts() {}
}

View File

@ -0,0 +1,191 @@
package com.jessebrault.ssg.buildscript
import com.jessebrault.ssg.SiteSpec
import groovy.transform.NullCheck
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.mockito.Mock
import org.mockito.junit.jupiter.MockitoExtension
import java.util.function.Consumer
import java.util.function.Function
import static com.jessebrault.ssg.buildscript.BuildScripts.runBuildScript
import static org.junit.jupiter.api.Assertions.assertEquals
import static org.mockito.Mockito.verify
final class BuildScriptsTests {
@NullCheck
@ExtendWith(MockitoExtension)
static final class ScriptFileTests {
/**
* Must be non-static, otherwise Groovy gets confused inside the Closures.
*
* TODO: use the FileUtil.copyResourceToWriter method
*/
@SuppressWarnings('GrMethodMayBeStatic')
private void copyLocalResourceToWriter(String name, Writer target) {
BuildScriptsTests.getResourceAsStream(name).withReader {
it.transferTo(target)
}
}
/**
* Must be non-static, otherwise Groovy gets confused inside the Closures.
*/
@SuppressWarnings('GrMethodMayBeStatic')
private File setupScripts(Collection<String> resourceNames) {
def tempDir = File.createTempDir()
new FileTreeBuilder(tempDir).tap {
resourceNames.each { String resourceName ->
file(resourceName).withWriter {
this.copyLocalResourceToWriter(resourceName, it)
}
}
}
tempDir
}
@Test
void simpleScript() {
def baseDir = this.setupScripts(['simple.groovy'])
def builds = runBuildScript('simple.groovy', baseDir.toURI().toURL())
assertEquals(1, builds.size())
assertEquals('test', builds[0].name)
}
@Test
void testImport() {
def baseDir = this.setupScripts(['testImport.groovy', 'TestHtmlTask.groovy'])
def builds = runBuildScript('testImport.groovy', baseDir.toURI().toURL())
assertEquals(1, builds.size())
assertEquals('test', builds[0].name)
}
@Test
void buildSrcTest() {
def baseDir = File.createTempDir()
new FileTreeBuilder(baseDir).tap {
file('buildSrcTest.groovy').withWriter {
this.copyLocalResourceToWriter('buildSrcTest.groovy', it)
}
dir('buildSrc') {
file('AnotherTask.groovy').withWriter {
this.copyLocalResourceToWriter('buildSrc/AnotherTask.groovy', it)
}
}
}
def builds = runBuildScript(
'buildSrcTest.groovy',
baseDir.toURI().toURL(),
[new File(baseDir, 'buildSrc').toURI().toURL()]
)
assertEquals(1, builds.size())
assertEquals('test', builds[0].name)
}
@Test
void withBinding(@Mock Consumer<String> stringConsumer) {
def baseDir = this.setupScripts(['withBinding.groovy'])
runBuildScript(
'withBinding.groovy',
baseDir.toURI().toURL(),
[],
[stringConsumer: stringConsumer]
)
verify(stringConsumer).accept('test')
}
}
@ExtendWith(MockitoExtension)
static final class ClosureScriptTests {
@Test
void simple() {
def result = runBuildScript {
build(name: 'test') { }
}
assertEquals(1, result.size())
assertEquals('test', result[0].name)
}
@Test
void oneBuildOutputDirWithFunction(@Mock Function<Build, OutputDir> mockOutputDirFunction) {
def r = runBuildScript {
build(name: 'test') {
outputDirFunction = mockOutputDirFunction
}
}
assertEquals(1, r.size())
def b0 = r[0]
assertEquals(mockOutputDirFunction, b0.outputDirFunction)
}
@Test
void oneBuildOutputDirWithFile() {
def f = new File('test')
def r = runBuildScript {
build(name: 'test') {
outputDir = f
}
}
assertEquals(1, r.size())
def b0 = r[0]
assertEquals(f, b0.outputDirFunction.apply(b0) as File)
}
@Test
void oneBuildOutputDirWithString() {
def r = runBuildScript {
build(name: 'test') {
outputDir = 'test'
}
}
assertEquals(1, r.size())
def b0 = r[0]
assertEquals('test', b0.outputDirFunction.apply(b0) as String)
}
@Test
void oneBuildSiteSpec() {
def r = runBuildScript {
build(name: 'test') {
siteSpec {
name = 'testSite'
baseUrl = 'https://testsite.com'
}
}
}
assertEquals(1, r.size())
def b0 = r[0]
assertEquals(new SiteSpec('testSite', 'https://testsite.com'), b0.siteSpec)
}
@Test
void oneBuildWithAbstractParent() {
def r = runBuildScript {
abstractBuild(name: 'parent') {
siteSpec {
name = 'Test Site'
baseUrl = 'https://test.com'
}
}
build(name: 'child', extending: 'parent') {
siteSpec { base ->
baseUrl = base.baseUrl + '/child'
}
}
}
assertEquals(1, r.size())
def b0 = r[0]
assertEquals(new SiteSpec('Test Site', 'https://test.com/child'), b0.siteSpec)
}
}
}

View File

@ -1,183 +0,0 @@
package com.jessebrault.ssg.buildscript
import com.jessebrault.ssg.SiteSpec
import groovy.transform.NullCheck
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.mockito.Mock
import org.mockito.junit.jupiter.MockitoExtension
import java.util.function.Consumer
import java.util.function.Function
import static org.junit.jupiter.api.Assertions.assertEquals
import static org.mockito.Mockito.verify
@NullCheck
@ExtendWith(MockitoExtension)
final class SimpleBuildScriptRunnerTests {
private final BuildScriptRunner runner = new SimpleBuildScriptRunner()
/**
* Must be non-static, otherwise Groovy gets confused inside the Closures.
*
* TODO: use the FileUtil.copyResourceToWriter method
*/
@SuppressWarnings('GrMethodMayBeStatic')
private void copyLocalResourceToWriter(String name, Writer target) {
SimpleBuildScriptRunnerTests.getResourceAsStream(name).withReader {
it.transferTo(target)
}
}
/**
* Must be non-static, otherwise Groovy gets confused inside the Closures.
*/
@SuppressWarnings('GrMethodMayBeStatic')
private File setupScripts(Collection<String> resourceNames) {
def tempDir = File.createTempDir()
new FileTreeBuilder(tempDir).tap {
resourceNames.each { String resourceName ->
file(resourceName).withWriter {
this.copyLocalResourceToWriter(resourceName, it)
}
}
}
tempDir
}
@Test
void simpleScript() {
def baseDir = this.setupScripts(['simple.groovy'])
def builds = this.runner.runBuildScript('simple.groovy', baseDir.toURI().toURL())
assertEquals(1, builds.size())
assertEquals('test', builds[0].name)
}
@Test
void testImport() {
def baseDir = this.setupScripts(['testImport.groovy', 'TestHtmlTask.groovy'])
def builds = this.runner.runBuildScript('testImport.groovy', baseDir.toURI().toURL())
assertEquals(1, builds.size())
assertEquals('test', builds[0].name)
}
@Test
void buildSrcTest() {
def baseDir = File.createTempDir()
new FileTreeBuilder(baseDir).tap {
file('buildSrcTest.groovy').withWriter {
this.copyLocalResourceToWriter('buildSrcTest.groovy', it)
}
dir('buildSrc') {
file('AnotherTask.groovy').withWriter {
this.copyLocalResourceToWriter('buildSrc/AnotherTask.groovy', it)
}
}
}
def builds = this.runner.runBuildScript(
'buildSrcTest.groovy',
baseDir.toURI().toURL(),
[new File(baseDir, 'buildSrc').toURI().toURL()]
)
assertEquals(1, builds.size())
assertEquals('test', builds[0].name)
}
@Test
void withBinding(@Mock Consumer<String> stringConsumer) {
def baseDir = this.setupScripts(['withBinding.groovy'])
this.runner.runBuildScript(
'withBinding.groovy',
baseDir.toURI().toURL(),
[],
[stringConsumer: stringConsumer]
)
verify(stringConsumer).accept('test')
}
@Test
void customScript() {
def result = this.runner.runBuildScript {
build(name: 'test') { }
}
assertEquals(1, result.size())
assertEquals('test', result[0].name)
}
@Test
void oneBuildOutputDirWithFunction(@Mock Function<Build, OutputDir> mockOutputDirFunction) {
def r = this.runner.runBuildScript {
build(name: 'test') {
outputDirFunction = mockOutputDirFunction
}
}
assertEquals(1, r.size())
def b0 = r[0]
assertEquals(mockOutputDirFunction, b0.outputDirFunction)
}
@Test
void oneBuildOutputDirWithFile() {
def f = new File('test')
def r = this.runner.runBuildScript {
build(name: 'test') {
outputDir = f
}
}
assertEquals(1, r.size())
def b0 = r[0]
assertEquals(f, b0.outputDirFunction.apply(b0) as File)
}
@Test
void oneBuildOutputDirWithString() {
def r = this.runner.runBuildScript {
build(name: 'test') {
outputDir = 'test'
}
}
assertEquals(1, r.size())
def b0 = r[0]
assertEquals('test', b0.outputDirFunction.apply(b0) as String)
}
@Test
void oneBuildSiteSpec() {
def r = this.runner.runBuildScript {
build(name: 'test') {
siteSpec {
name = 'testSite'
baseUrl = 'https://testsite.com'
}
}
}
assertEquals(1, r.size())
def b0 = r[0]
assertEquals(new SiteSpec('testSite', 'https://testsite.com'), b0.siteSpec)
}
@Test
void oneBuildWithAbstractParent() {
def r = this.runner.runBuildScript {
abstractBuild(name: 'parent') {
siteSpec {
name = 'Test Site'
baseUrl = 'https://test.com'
}
}
build(name: 'child', extending: 'parent') {
siteSpec { base ->
baseUrl = base.baseUrl + '/child'
}
}
}
assertEquals(1, r.size())
def b0 = r[0]
assertEquals(new SiteSpec('Test Site', 'https://test.com/child'), b0.siteSpec)
}
}