Worked on buildscript and added some annotations and views.
This commit is contained in:
parent
c502727243
commit
76c6280b5d
1
api/src/main/groovy/com/jessebrault/ssg/.gitignore
vendored
Normal file
1
api/src/main/groovy/com/jessebrault/ssg/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
!build
|
@ -1,6 +1,6 @@
|
||||
package com.jessebrault.ssg
|
||||
|
||||
import com.jessebrault.ssg.buildscript.Build
|
||||
import com.jessebrault.ssg.buildscript.BuildSpec
|
||||
import com.jessebrault.ssg.buildscript.BuildScriptConfiguratorFactory
|
||||
import com.jessebrault.ssg.buildscript.FileBuildScriptGetter
|
||||
import com.jessebrault.ssg.util.Diagnostic
|
||||
@ -23,7 +23,7 @@ final class BuildScriptBasedStaticSiteGenerator implements StaticSiteGenerator {
|
||||
|
||||
private final Collection<URL> buildScriptClassLoaderUrls
|
||||
private final @Nullable File buildScript
|
||||
private final Collection<Build> builds = []
|
||||
private final Collection<BuildSpec> builds = []
|
||||
|
||||
private GroovyClassLoader buildScriptClassLoader
|
||||
|
||||
@ -59,7 +59,7 @@ final class BuildScriptBasedStaticSiteGenerator implements StaticSiteGenerator {
|
||||
logger.info('running buildScript: {}', this.buildScript)
|
||||
def buildScriptRunner = new FileBuildScriptGetter(this.buildScriptClassLoaderUrls)
|
||||
this.buildScriptClassLoader = buildScriptRunner.getBuildScriptClassLoader()
|
||||
def result = buildScriptRunner.getBuildInfo(
|
||||
def result = buildScriptRunner.getBuildScript(
|
||||
this.buildScript.name,
|
||||
[args: buildScriptArgs]
|
||||
) { base ->
|
||||
@ -86,7 +86,7 @@ final class BuildScriptBasedStaticSiteGenerator implements StaticSiteGenerator {
|
||||
@NullCheck(includeGenerated = true)
|
||||
@EqualsAndHashCode
|
||||
private static final class IncludedBuildsResult {
|
||||
final Collection<Build> builds
|
||||
final Collection<BuildSpec> builds
|
||||
final Collection<Diagnostic> diagnostics
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
package com.jessebrault.ssg
|
||||
|
||||
import com.jessebrault.ssg.buildscript.Build
|
||||
import com.jessebrault.ssg.buildscript.BuildSpec
|
||||
import com.jessebrault.ssg.task.Task
|
||||
import com.jessebrault.ssg.util.Result
|
||||
|
||||
interface BuildTasksConverter {
|
||||
Result<Collection<Task>> convert(Build buildScriptResult)
|
||||
Result<Collection<Task>> convert(BuildSpec buildScriptResult)
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.jessebrault.ssg
|
||||
|
||||
import com.jessebrault.ssg.buildscript.Build
|
||||
import com.jessebrault.ssg.buildscript.BuildSpec
|
||||
import com.jessebrault.ssg.task.Task
|
||||
import com.jessebrault.ssg.task.TaskSpec
|
||||
import com.jessebrault.ssg.util.Diagnostic
|
||||
@ -9,7 +9,7 @@ import com.jessebrault.ssg.util.Result
|
||||
final class SimpleBuildTasksConverter implements BuildTasksConverter {
|
||||
|
||||
@Override
|
||||
Result<Collection<Task>> convert(Build build) {
|
||||
Result<Collection<Task>> convert(BuildSpec build) {
|
||||
def taskSpec = new TaskSpec(
|
||||
build.name,
|
||||
build.outputDirFunction.apply(build).asFile(),
|
||||
|
37
api/src/main/groovy/com/jessebrault/ssg/build/Build.groovy
Normal file
37
api/src/main/groovy/com/jessebrault/ssg/build/Build.groovy
Normal file
@ -0,0 +1,37 @@
|
||||
package com.jessebrault.ssg.build
|
||||
|
||||
import com.jessebrault.ssg.model.Model
|
||||
import com.jessebrault.ssg.page.Page
|
||||
import groowt.util.fp.provider.NamedSetProvider
|
||||
|
||||
import static com.jessebrault.ssg.util.ObjectUtil.*
|
||||
|
||||
class Build {
|
||||
|
||||
final String name
|
||||
final String siteName
|
||||
final String baseUrl
|
||||
final File outputDir
|
||||
final Map globals
|
||||
final Set<File> textsDirs
|
||||
final NamedSetProvider<Model> models
|
||||
final NamedSetProvider<Page> pages
|
||||
|
||||
Build(Map args) {
|
||||
this.name = requireString(args.name)
|
||||
this.siteName = requireString(args.siteName)
|
||||
this.baseUrl = requireString(args.baseUrl)
|
||||
this.outputDir = requireFile(args.outputDir)
|
||||
this.globals = requireMap(args.globals)
|
||||
this.textsDirs = requireSet(args.textsDirs)
|
||||
this.models = requireType(NamedSetProvider, args.models)
|
||||
this.pages = requireType(NamedSetProvider, args.pages)
|
||||
}
|
||||
|
||||
void doBuild() {
|
||||
// set up object factory for di
|
||||
// container should have: Build and all its properties
|
||||
// container should also have @Text, @Texts, @Model, @Models, and @Page resolvers
|
||||
}
|
||||
|
||||
}
|
20
api/src/main/groovy/com/jessebrault/ssg/build/Page.groovy
Normal file
20
api/src/main/groovy/com/jessebrault/ssg/build/Page.groovy
Normal file
@ -0,0 +1,20 @@
|
||||
package com.jessebrault.ssg.build
|
||||
|
||||
import jakarta.inject.Qualifier
|
||||
|
||||
import java.lang.annotation.ElementType
|
||||
import java.lang.annotation.Retention
|
||||
import java.lang.annotation.RetentionPolicy
|
||||
import java.lang.annotation.Target
|
||||
|
||||
@Qualifier
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target([ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD])
|
||||
@interface Page {
|
||||
|
||||
/**
|
||||
* May be either a page name or a path starting with '/'
|
||||
*/
|
||||
String value()
|
||||
|
||||
}
|
20
api/src/main/groovy/com/jessebrault/ssg/build/Pages.groovy
Normal file
20
api/src/main/groovy/com/jessebrault/ssg/build/Pages.groovy
Normal file
@ -0,0 +1,20 @@
|
||||
package com.jessebrault.ssg.build
|
||||
|
||||
import jakarta.inject.Qualifier
|
||||
|
||||
import java.lang.annotation.ElementType
|
||||
import java.lang.annotation.Retention
|
||||
import java.lang.annotation.RetentionPolicy
|
||||
import java.lang.annotation.Target
|
||||
|
||||
@Qualifier
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target([ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD])
|
||||
@interface Pages {
|
||||
|
||||
/**
|
||||
* Names of pages and/or globs (starting with '/') of pages
|
||||
*/
|
||||
String[] value()
|
||||
|
||||
}
|
20
api/src/main/groovy/com/jessebrault/ssg/build/Text.groovy
Normal file
20
api/src/main/groovy/com/jessebrault/ssg/build/Text.groovy
Normal file
@ -0,0 +1,20 @@
|
||||
package com.jessebrault.ssg.build
|
||||
|
||||
import jakarta.inject.Qualifier
|
||||
|
||||
import java.lang.annotation.ElementType
|
||||
import java.lang.annotation.Retention
|
||||
import java.lang.annotation.RetentionPolicy
|
||||
import java.lang.annotation.Target
|
||||
|
||||
@Qualifier
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target([ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD])
|
||||
@interface Text {
|
||||
|
||||
/**
|
||||
* The name of the text, or the path of the text, starting with '/'
|
||||
*/
|
||||
String value()
|
||||
|
||||
}
|
20
api/src/main/groovy/com/jessebrault/ssg/build/Texts.groovy
Normal file
20
api/src/main/groovy/com/jessebrault/ssg/build/Texts.groovy
Normal file
@ -0,0 +1,20 @@
|
||||
package com.jessebrault.ssg.build
|
||||
|
||||
import jakarta.inject.Qualifier
|
||||
|
||||
import java.lang.annotation.ElementType
|
||||
import java.lang.annotation.Retention
|
||||
import java.lang.annotation.RetentionPolicy
|
||||
import java.lang.annotation.Target
|
||||
|
||||
@Qualifier
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target([ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD])
|
||||
@interface Texts {
|
||||
|
||||
/**
|
||||
* Names of texts and/or globs (starting with '/') of texts
|
||||
*/
|
||||
String[] value()
|
||||
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
package com.jessebrault.ssg.buildscript
|
||||
|
||||
import com.jessebrault.ssg.model.Model
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.NullCheck
|
||||
import groowt.util.fp.property.Property
|
||||
import groowt.util.fp.provider.NamedProvider
|
||||
import groowt.util.fp.provider.NamedSetProvider
|
||||
import groowt.util.fp.provider.Provider
|
||||
import groowt.util.fp.provider.SetProvider
|
||||
|
||||
import static java.util.Objects.requireNonNull
|
||||
|
||||
@NullCheck(includeGenerated = true)
|
||||
@EqualsAndHashCode
|
||||
final class Build {
|
||||
|
||||
final Collection<String> includedBuilds
|
||||
final Property<String> name
|
||||
final Property<String> siteName
|
||||
final Property<String> baseUrl
|
||||
final Provider<File> outputDir
|
||||
final Provider<Map<String, Object>> globals
|
||||
final Set<Provider<File>> textsDirs
|
||||
final Set<NamedProvider<Model>> models
|
||||
|
||||
@SuppressWarnings('GroovyAssignabilityCheck')
|
||||
Build(Map args) {
|
||||
this.includedBuilds = requireNonNull(args.includedBuilds)
|
||||
this.name = requireNonNull(args.name)
|
||||
this.siteName = requireNonNull(args.siteName)
|
||||
this.baseUrl = requireNonNull(args.baseUrl)
|
||||
this.outputDir = requireNonNull(args.outputDir)
|
||||
this.globals = requireNonNull(args.globals)
|
||||
this.textsDirs = requireNonNull(args.textsDirs)
|
||||
this.models = requireNonNull(args.models)
|
||||
}
|
||||
|
||||
@Override
|
||||
String toString() {
|
||||
"Build(name: ${ this.name })"
|
||||
}
|
||||
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
package com.jessebrault.ssg.buildscript
|
||||
|
||||
import com.jessebrault.ssg.buildscript.delegates.BuildDelegate
|
||||
import groovy.transform.NullCheck
|
||||
import groovy.transform.TupleConstructor
|
||||
|
||||
@NullCheck
|
||||
@TupleConstructor(includeFields = true)
|
||||
class BuildDelegateToBuildConverter {
|
||||
|
||||
protected Build getFromDelegate(String name, BuildDelegate delegate) {
|
||||
new Build(
|
||||
name: name,
|
||||
siteName: delegate.siteName,
|
||||
baseUrl: delegate.baseUrl,
|
||||
outputDir: delegate.outputDir,
|
||||
globals: delegate.globals,
|
||||
models: delegate.models
|
||||
)
|
||||
}
|
||||
|
||||
protected void getFromBuild(Build source) {
|
||||
new BuildDelegate().tap {
|
||||
siteName(source.siteName)
|
||||
baseUrl(source.siteName)
|
||||
outputDir(source.outputDir)
|
||||
globals.set(source.globals)
|
||||
textsDirs(source.textsDirs)
|
||||
models(source.models)
|
||||
}
|
||||
}
|
||||
|
||||
private final FileBuildScriptGetter buildScriptGetter
|
||||
private final File buildScriptsDir
|
||||
|
||||
Build convert(String name, BuildScriptBase buildScript) {
|
||||
final BuildDelegate delegate
|
||||
if (buildScript.extending != null) {
|
||||
def extendingFrom = buildScriptGetter.getBuildInfo(buildScript.extending)
|
||||
def build = this.convert(buildScript.extending, extendingFrom)
|
||||
delegate = this.getFromBuild(build)
|
||||
} else {
|
||||
delegate = new BuildDelegate()
|
||||
}
|
||||
def cl = buildScript.buildClosure
|
||||
cl.delegate = delegate
|
||||
cl()
|
||||
this.getFromDelegate(name, delegate)
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package com.jessebrault.ssg.buildscript
|
||||
|
||||
import com.jessebrault.ssg.buildscript.delegates.BuildDelegate
|
||||
import groovy.transform.NullCheck
|
||||
import groovy.transform.TupleConstructor
|
||||
|
||||
@NullCheck
|
||||
@TupleConstructor(includeFields = true)
|
||||
class BuildDelegateToBuildSpecConverter {
|
||||
|
||||
private final FileBuildScriptGetter buildScriptGetter
|
||||
|
||||
protected BuildSpec getFromDelegate(String name, BuildDelegate delegate) {
|
||||
new BuildSpec(
|
||||
name: name,
|
||||
siteName: delegate.siteName,
|
||||
baseUrl: delegate.baseUrl,
|
||||
outputDir: delegate.outputDir,
|
||||
globals: delegate.globals,
|
||||
textsDirs: delegate.textsDirs,
|
||||
models: delegate.models
|
||||
)
|
||||
}
|
||||
|
||||
BuildSpec convert(final String name, final BuildScriptBase buildScript) {
|
||||
final Deque<BuildScriptBase> buildHierarchy = new LinkedList<>()
|
||||
buildHierarchy.push(buildScript)
|
||||
String extending = buildScript.extending
|
||||
while (extending != null) {
|
||||
def from = this.buildScriptGetter.getBuildScript(extending)
|
||||
buildHierarchy.push(from)
|
||||
extending = from.extending
|
||||
}
|
||||
|
||||
def delegate = new BuildDelegate()
|
||||
while (!buildHierarchy.isEmpty()) {
|
||||
def currentScript = buildHierarchy.pop()
|
||||
currentScript.buildClosure.delegate = delegate
|
||||
currentScript.buildClosure()
|
||||
}
|
||||
|
||||
this.getFromDelegate(name, delegate)
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package com.jessebrault.ssg.buildscript
|
||||
|
||||
import com.jessebrault.ssg.model.Model
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.NullCheck
|
||||
import groowt.util.fp.provider.NamedProvider
|
||||
import groowt.util.fp.provider.Provider
|
||||
|
||||
import static com.jessebrault.ssg.util.ObjectUtil.*
|
||||
|
||||
@NullCheck(includeGenerated = true)
|
||||
@EqualsAndHashCode
|
||||
final class BuildSpec {
|
||||
|
||||
final String name
|
||||
final Provider<String> siteName
|
||||
final Provider<String> baseUrl
|
||||
final Provider<File> outputDir
|
||||
final Provider<Map<String, Object>> globals
|
||||
final Set<Provider<File>> textsDirs
|
||||
|
||||
@SuppressWarnings('GroovyAssignabilityCheck')
|
||||
BuildSpec(Map args) {
|
||||
this.name = requireString(args.name)
|
||||
this.siteName = requireProvider(args.siteName)
|
||||
this.baseUrl = requireProvider(args.baseUrl)
|
||||
this.outputDir = requireProvider(args.outputDir)
|
||||
this.globals = requireMap(args.globals)
|
||||
this.textsDirs = requireSet(args.textsDirs)
|
||||
}
|
||||
|
||||
@Override
|
||||
String toString() {
|
||||
"Build(name: ${ this.name })"
|
||||
}
|
||||
|
||||
}
|
@ -7,11 +7,10 @@ import groovy.transform.TupleConstructor
|
||||
@TupleConstructor(includeFields = true)
|
||||
final class FileBuildScriptGetter {
|
||||
|
||||
private final File projectRoot
|
||||
private final GroovyClassLoader gcl
|
||||
private final GroovyClassLoader groovyClassLoader
|
||||
|
||||
BuildScriptBase getBuildInfo(String name) {
|
||||
Class<?> scriptClass = this.gcl.loadClass(name, true, false)
|
||||
BuildScriptBase getBuildScript(String name) {
|
||||
Class<?> scriptClass = this.groovyClassLoader.loadClass(name, true, false)
|
||||
def scriptObject = scriptClass.getConstructor().newInstance()
|
||||
assert scriptObject instanceof BuildScriptBase
|
||||
scriptObject
|
||||
|
@ -1,14 +1,9 @@
|
||||
package com.jessebrault.ssg.buildscript.delegates
|
||||
|
||||
import com.jessebrault.ssg.model.Model
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.NullCheck
|
||||
import groowt.util.fp.property.Property
|
||||
import groowt.util.fp.provider.DefaultNamedProvider
|
||||
import groowt.util.fp.provider.DefaultNamedSetProvider
|
||||
import groowt.util.fp.provider.DefaultSetProvider
|
||||
import groowt.util.fp.provider.NamedProvider
|
||||
import groowt.util.fp.provider.NamedSetProvider
|
||||
import groowt.util.fp.provider.Provider
|
||||
import groowt.util.fp.provider.SetProvider
|
||||
|
||||
@ -33,7 +28,6 @@ final class BuildDelegate {
|
||||
}
|
||||
|
||||
private final Set<Provider<File>> textsDirs = []
|
||||
private final Set<NamedProvider<Model>> models = []
|
||||
|
||||
void siteName(String siteName) {
|
||||
this.siteName.set(siteName)
|
||||
@ -85,19 +79,4 @@ final class BuildDelegate {
|
||||
new DefaultSetProvider(this.textsDirs)
|
||||
}
|
||||
|
||||
void models(@DelegatesTo(ModelsDelegate) Closure modelsClosure) {
|
||||
def modelsDelegate = new ModelsDelegate()
|
||||
modelsClosure.delegate = modelsDelegate
|
||||
modelsClosure()
|
||||
models.addAll(modelsDelegate.result)
|
||||
}
|
||||
|
||||
void models(Set<NamedProvider<Model>> models) {
|
||||
this.models.addAll(models)
|
||||
}
|
||||
|
||||
NamedSetProvider<Model> getModels() {
|
||||
new DefaultNamedSetProvider(this.models)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,49 +0,0 @@
|
||||
package com.jessebrault.ssg.buildscript.delegates
|
||||
|
||||
import com.jessebrault.ssg.model.Model
|
||||
import com.jessebrault.ssg.model.Models
|
||||
import groowt.util.fp.provider.DefaultNamedProvider
|
||||
import groowt.util.fp.provider.NamedProvider
|
||||
import groowt.util.fp.provider.Provider
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
import java.util.function.Supplier
|
||||
|
||||
final class ModelsDelegate {
|
||||
|
||||
private final Map<String, Provider<Model>> modelsMap = [:]
|
||||
|
||||
void add(String name, Object modelObject) {
|
||||
this.modelsMap.put(name) { Models.of(name, modelObject ) }
|
||||
}
|
||||
|
||||
void add(Model model) {
|
||||
this.modelsMap.put(model.name) { model }
|
||||
}
|
||||
|
||||
void add(NamedProvider<Model> namedModelProvider) {
|
||||
this.modelsMap.put(namedModelProvider.name, namedModelProvider)
|
||||
}
|
||||
|
||||
void add(String name, Provider<Model> modelProvider) {
|
||||
this.modelsMap.put(name, modelProvider)
|
||||
}
|
||||
|
||||
void add(String name, Supplier objectSupplier) {
|
||||
this.modelsMap.put(name) { Models.ofSupplier(name, objectSupplier) }
|
||||
}
|
||||
|
||||
void addAll(Map<String, Object> namesAndModels) {
|
||||
namesAndModels.each { name, modelObject ->
|
||||
this.add(name, modelObject)
|
||||
}
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
Set<NamedProvider<Model>> getResult() {
|
||||
this.modelsMap.inject([] as Set<NamedProvider<Model>>) { acc, name, modelProvider ->
|
||||
acc << new DefaultNamedProvider(name, modelProvider)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
package com.jessebrault.ssg.mutable;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.*;
|
||||
|
||||
@ApiStatus.Experimental
|
||||
@Deprecated
|
||||
public interface Mutable<T> {
|
||||
T get();
|
||||
void set(T t);
|
||||
void unset();
|
||||
|
||||
boolean isPresent();
|
||||
|
||||
default boolean isEmpty() {
|
||||
return !this.isPresent();
|
||||
}
|
||||
|
||||
void filterInPlace(Predicate<T> filter);
|
||||
void mapInPlace(UnaryOperator<T> mapper);
|
||||
<U> void zipInPlace(Mutable<U> other, Supplier<T> onEmpty, Supplier<U> onOtherEmpty, BiFunction<T, U, T> zipper);
|
||||
|
||||
<U> U match(Supplier<U> onEmpty, Function<T, U> onPresentMapper);
|
||||
T getOrElse(Supplier<T> onEmpty);
|
||||
|
||||
<U> Mutable<U> chain(Function<T, Mutable<U>> mapper);
|
||||
<U> Mutable<U> map(Function<T, U> mapper);
|
||||
|
||||
<U, R> Mutable<R> zip(Mutable<U> other, BiFunction<T, U, R> zipper);
|
||||
|
||||
Optional<T> asOptional();
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
package com.jessebrault.ssg.mutable;
|
||||
|
||||
import com.jessebrault.ssg.util.Monoid;
|
||||
import com.jessebrault.ssg.util.Monoids;
|
||||
import com.jessebrault.ssg.util.Semigroup;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@ApiStatus.Experimental
|
||||
public final class Mutables {
|
||||
|
||||
public static <T> Monoid<Mutable<T>> getMonoid(final Semigroup<T> tSemigroup) {
|
||||
return Monoids.of(Mutables.getEmpty(), (m0, m1) -> {
|
||||
if (m0.isPresent() && m1.isPresent()) {
|
||||
return get(tSemigroup.getConcat().apply(m0.get(), m1.get()));
|
||||
} else if (m0.isPresent()) {
|
||||
return m0;
|
||||
} else if (m1.isPresent()) {
|
||||
return m1;
|
||||
} else {
|
||||
return getEmpty();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static <T> @NotNull Mutable<T> getEmpty() {
|
||||
return new SimpleMutable<>();
|
||||
}
|
||||
|
||||
public static <T> Mutable<T> get(T initialValue) {
|
||||
return new SimpleMutable<>(initialValue);
|
||||
}
|
||||
|
||||
private Mutables() {}
|
||||
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
package com.jessebrault.ssg.mutable;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.*;
|
||||
|
||||
@ApiStatus.Experimental
|
||||
final class SimpleMutable<T> implements Mutable<T> {
|
||||
|
||||
private T t;
|
||||
|
||||
public SimpleMutable(T initialValue) {
|
||||
this.t = initialValue;
|
||||
}
|
||||
|
||||
public SimpleMutable() {}
|
||||
|
||||
@Override
|
||||
public T get() {
|
||||
if (this.t == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
return this.t;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(T t) {
|
||||
this.t = t;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unset() {
|
||||
this.t = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPresent() {
|
||||
return this.t != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void filterInPlace(Predicate<T> filter) {
|
||||
if (this.t != null && !filter.test(this.t)) {
|
||||
this.unset();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mapInPlace(UnaryOperator<T> mapper) {
|
||||
this.t = mapper.apply(this.t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <U> void zipInPlace(Mutable<U> other, Supplier<T> onEmpty, Supplier<U> onOtherEmpty, BiFunction<T, U, T> zipper) {
|
||||
this.t = zipper.apply(
|
||||
this.isPresent() ? this.t : onEmpty.get(),
|
||||
other.isPresent() ? other.get() : onOtherEmpty.get()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <U> U match(Supplier<U> onEmpty, Function<T, U> onPresentMapper) {
|
||||
return this.t != null ? onPresentMapper.apply(this.t) : onEmpty.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getOrElse(Supplier<T> other) {
|
||||
return this.t != null ? this.t : other.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <U> Mutable<U> chain(Function<T, Mutable<U>> mapper) {
|
||||
return this.map(mapper).get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <U> Mutable<U> map(Function<T, U> mapper) {
|
||||
return this.t != null ? Mutables.get(mapper.apply(this.t)) : Mutables.getEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <U, R> Mutable<R> zip(Mutable<U> other, BiFunction<T, U, R> zipper) {
|
||||
return this.isPresent() && other.isPresent()
|
||||
? Mutables.get(zipper.apply(this.get(), other.get()))
|
||||
: Mutables.getEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<T> asOptional() {
|
||||
return Optional.ofNullable(this.t);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package com.jessebrault.ssg.util
|
||||
|
||||
import groowt.util.fp.property.Property
|
||||
import groowt.util.fp.provider.Provider
|
||||
|
||||
import static java.util.Objects.requireNonNull
|
||||
|
||||
final class ObjectUtil {
|
||||
|
||||
static <T> T requireType(Class<T> type, Object t) {
|
||||
type.cast(requireNonNull(t))
|
||||
}
|
||||
|
||||
static String requireString(s) {
|
||||
requireNonNull(s) as String
|
||||
}
|
||||
|
||||
static File requireFile(f) {
|
||||
requireNonNull(f) as File
|
||||
}
|
||||
|
||||
static Map requireMap(m) {
|
||||
requireNonNull(m) as Map
|
||||
}
|
||||
|
||||
static Set requireSet(s) {
|
||||
requireNonNull(s) as Set
|
||||
}
|
||||
|
||||
static Property requireProperty(p) {
|
||||
requireNonNull(p) as Property
|
||||
}
|
||||
|
||||
static Provider requireProvider(p) {
|
||||
requireNonNull(p) as Provider
|
||||
}
|
||||
|
||||
private ObjectUtil() {}
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package com.jessebrault.ssg.view
|
||||
|
||||
import groowt.view.StandardGStringTemplateView
|
||||
|
||||
class GStringPageView extends StandardGStringTemplateView implements PageView {
|
||||
|
||||
String pageTitle
|
||||
String url
|
||||
|
||||
GStringPageView(Map<String, Object> args) {
|
||||
super(args)
|
||||
}
|
||||
|
||||
}
|
13
api/src/main/groovy/com/jessebrault/ssg/view/PageView.groovy
Normal file
13
api/src/main/groovy/com/jessebrault/ssg/view/PageView.groovy
Normal file
@ -0,0 +1,13 @@
|
||||
package com.jessebrault.ssg.view
|
||||
|
||||
import groowt.view.View
|
||||
|
||||
interface PageView extends View {
|
||||
|
||||
String getPageTitle()
|
||||
void setPageTitle(String pageName)
|
||||
|
||||
String getUrl()
|
||||
void setUrl(String url)
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package com.jessebrault.ssg.view
|
||||
|
||||
import groowt.view.web.BaseWebViewComponent
|
||||
|
||||
class WvcPageView extends BaseWebViewComponent implements PageView {
|
||||
|
||||
String pageTitle
|
||||
String url
|
||||
|
||||
WvcPageView(Object source) {
|
||||
super(source)
|
||||
}
|
||||
|
||||
}
|
@ -1,123 +0,0 @@
|
||||
package com.jessebrault.ssg.buildscript
|
||||
|
||||
import com.jessebrault.ssg.SiteSpec
|
||||
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.Function
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals
|
||||
|
||||
@ExtendWith(MockitoExtension)
|
||||
final class BuildScriptBaseTests {
|
||||
|
||||
private static Collection<BuildSpec> scriptToBuildSpecs(
|
||||
@DelegatesTo(value = BuildScriptBase, strategy = Closure.DELEGATE_FIRST)
|
||||
Closure<?> script
|
||||
) {
|
||||
def base = new BuildScriptBase() {
|
||||
|
||||
@Override
|
||||
Object run() {
|
||||
script.delegate = this
|
||||
script.resolveStrategy = Closure.DELEGATE_FIRST
|
||||
script()
|
||||
}
|
||||
|
||||
}
|
||||
base.run()
|
||||
base.buildSpecs
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
private static Collection<Build> scriptToBuilds(
|
||||
@DelegatesTo(value = BuildScriptBase, strategy = Closure.DELEGATE_FIRST)
|
||||
Closure<?> script
|
||||
) {
|
||||
BuildSpecUtil.getBuilds(scriptToBuildSpecs(script))
|
||||
}
|
||||
|
||||
@Test
|
||||
void oneBuildWithName0() {
|
||||
def r = scriptToBuildSpecs {
|
||||
build(name: 'test') { }
|
||||
}
|
||||
assertEquals(1, r.size())
|
||||
def b0 = r[0]
|
||||
assertEquals('test', b0.name)
|
||||
}
|
||||
|
||||
@Test
|
||||
void oneBuildWithName1() {
|
||||
def r = scriptToBuildSpecs {
|
||||
build(name: 'test') { }
|
||||
}
|
||||
assertEquals(1, r.size())
|
||||
def b0 = r[0]
|
||||
assertEquals('test', b0.name)
|
||||
}
|
||||
|
||||
@Test
|
||||
void twoBuildsNotRelated() {
|
||||
def r = scriptToBuildSpecs {
|
||||
build(name: 'b0') { }
|
||||
build(name: 'b1') { }
|
||||
}
|
||||
assertEquals(2, r.size())
|
||||
}
|
||||
|
||||
@Test
|
||||
void childParentBuild() {
|
||||
def r = scriptToBuildSpecs {
|
||||
build(name: 'child', extending: 'parent') { }
|
||||
build(name: 'parent') { }
|
||||
}
|
||||
assertEquals(2, r.size())
|
||||
assertEquals(
|
||||
[
|
||||
BuildSpec.get(name: 'child', extending: ['parent']),
|
||||
BuildSpec.get(name: 'parent')
|
||||
],
|
||||
r
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
void threeGenerations() {
|
||||
def r = scriptToBuildSpecs {
|
||||
build(name: 'child', extending: 'parent') { }
|
||||
build(name: 'parent', extending: 'grandparent') { }
|
||||
build(name: 'grandparent') { }
|
||||
}
|
||||
assertEquals(3, r.size())
|
||||
assertEquals(
|
||||
[
|
||||
BuildSpec.get(name: 'child', extending: ['parent']),
|
||||
BuildSpec.get(name: 'parent', extending: ['grandparent']),
|
||||
BuildSpec.get(name: 'grandparent')
|
||||
],
|
||||
r
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
void siblingsAndParent() {
|
||||
def r = scriptToBuildSpecs {
|
||||
build(name: 'child0', extending: 'parent') { }
|
||||
build(name: 'child1', extending: 'parent') { }
|
||||
build(name: 'parent') { }
|
||||
}
|
||||
assertEquals(3, r.size())
|
||||
assertEquals(
|
||||
[
|
||||
BuildSpec.get(name: 'child0', extending: ['parent']),
|
||||
BuildSpec.get(name: 'child1', extending: ['parent']),
|
||||
BuildSpec.get(name: 'parent')
|
||||
],
|
||||
r
|
||||
)
|
||||
}
|
||||
|
||||
}
|
@ -1,190 +0,0 @@
|
||||
package com.jessebrault.ssg.buildscript
|
||||
|
||||
import com.jessebrault.ssg.SiteSpec
|
||||
import groovy.transform.NullCheck
|
||||
import org.junit.jupiter.api.Disabled
|
||||
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 BuildScriptsTests {
|
||||
|
||||
/**
|
||||
* 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
|
||||
}
|
||||
|
||||
private static Collection<Build> getBuilds(
|
||||
String scriptName,
|
||||
Collection<URL> urls,
|
||||
Map<String, Object> binding = [:],
|
||||
Consumer<BuildScriptBase> configureBase = { }
|
||||
) {
|
||||
new FileBuildScriptGetter(urls).getBuildInfo(scriptName, binding, configureBase)
|
||||
}
|
||||
|
||||
@Test
|
||||
void simpleScript() {
|
||||
def baseDir = this.setupScripts(['simple.groovy'])
|
||||
def builds = getBuilds('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 = getBuilds('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 = getBuilds(
|
||||
'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'])
|
||||
getBuilds('withBinding.groovy', [baseDir.toURI().toURL()], [stringConsumer: stringConsumer])
|
||||
verify(stringConsumer).accept('test')
|
||||
}
|
||||
|
||||
@Test
|
||||
void simple() {
|
||||
def result = runClosureScript {
|
||||
build(name: 'test') { }
|
||||
}
|
||||
assertEquals(1, result.size())
|
||||
assertEquals('test', result[0].name)
|
||||
}
|
||||
|
||||
@Test
|
||||
void oneBuildOutputDirWithFunction(@Mock Function<Build, OutputDir> mockOutputDirFunction) {
|
||||
def r = runClosureScript {
|
||||
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 = runClosureScript {
|
||||
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 = runClosureScript {
|
||||
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 = runClosureScript {
|
||||
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
|
||||
@Disabled
|
||||
@Deprecated(forRemoval = true)
|
||||
void oneBuildWithAbstractParent() {
|
||||
def r = runClosureScript {
|
||||
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)
|
||||
}
|
||||
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
package com.jessebrault.ssg.buildscript
|
||||
|
||||
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.Function
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals
|
||||
|
||||
@ExtendWith(MockitoExtension)
|
||||
final class BuildSpecUtilTests {
|
||||
|
||||
@Test
|
||||
void overwrittenOutputDir(@Mock Function<Build, OutputDir> spec1OutputDirFunction) {
|
||||
def spec0 = BuildSpec.get('spec0', true, []) {
|
||||
outputDirFunction = { }
|
||||
}
|
||||
def spec1 = BuildSpec.get('spec1', false, ['spec0']) {
|
||||
outputDirFunction = spec1OutputDirFunction
|
||||
}
|
||||
def r = BuildSpecUtil.getBuilds([spec0, spec1])
|
||||
assertEquals(1, r.size())
|
||||
def b0 = r[0]
|
||||
assertEquals('spec1', b0.name)
|
||||
assertEquals(spec1OutputDirFunction, b0.outputDirFunction)
|
||||
}
|
||||
|
||||
@Test
|
||||
void outputDirManualConcat() {
|
||||
def spec0 = BuildSpec.get('spec0', true, []) {
|
||||
outputDirFunction = OutputDirFunctions.DEFAULT
|
||||
}
|
||||
def spec1 = BuildSpec.get('spec1', false, ['spec0']) {
|
||||
outputDirFunction {
|
||||
it.andThen {
|
||||
new OutputDir(new File(it.asFile(), 'spec1'))
|
||||
}
|
||||
}
|
||||
}
|
||||
def r = BuildSpecUtil.getBuilds([spec0, spec1])
|
||||
assertEquals(1, r.size())
|
||||
def b0 = r[0]
|
||||
assertEquals('spec1', b0.name)
|
||||
assertEquals('spec1/spec1', b0.outputDirFunction.apply(b0).asString())
|
||||
}
|
||||
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
package com.jessebrault.ssg.buildscript
|
||||
|
||||
import com.jessebrault.ssg.SiteSpec
|
||||
import com.jessebrault.ssg.task.TaskFactory
|
||||
import com.jessebrault.ssg.task.TaskFactorySpec
|
||||
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.Function
|
||||
import java.util.function.Supplier
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals
|
||||
|
||||
@ExtendWith(MockitoExtension)
|
||||
final class BuildTests {
|
||||
|
||||
@Test
|
||||
void twoEmptiesEqual() {
|
||||
def b0 = Build.getEmpty()
|
||||
def b1 = Build.getEmpty()
|
||||
assertEquals(b0, b1)
|
||||
}
|
||||
|
||||
@Test
|
||||
void ifName0BlankTakeName1() {
|
||||
def b0 = Build.get(name: '')
|
||||
def b1 = Build.get(name: 'test')
|
||||
def sum = b0 + b1
|
||||
assertEquals('test', sum.name)
|
||||
}
|
||||
|
||||
@Test
|
||||
void ifName0NotBlankTakeName0() {
|
||||
def b0 = Build.get(name: 'b0')
|
||||
def b1 = Build.get(name: 'b1')
|
||||
def sum = b0 + b1
|
||||
assertEquals('b0', sum.name)
|
||||
}
|
||||
|
||||
@Test
|
||||
void ifOutputDirFunction0DefaultTake1(@Mock Function<Build, OutputDir> b1OutputDirFunction) {
|
||||
def b0 = Build.get(outputDirFunction: OutputDirFunctions.DEFAULT)
|
||||
def b1 = Build.get(outputDirFunction: b1OutputDirFunction)
|
||||
def sum = b0 + b1
|
||||
assertEquals(b1OutputDirFunction, sum.outputDirFunction)
|
||||
}
|
||||
|
||||
@Test
|
||||
void siteSpecsAdded() {
|
||||
def b0 = Build.get(
|
||||
siteSpec: new SiteSpec('test', '')
|
||||
)
|
||||
def b1 = Build.get(
|
||||
siteSpec: new SiteSpec('', 'test')
|
||||
)
|
||||
def sum = b0 + b1
|
||||
assertEquals(new SiteSpec('test', 'test'), sum.siteSpec)
|
||||
}
|
||||
|
||||
@Test
|
||||
void globalsAdded() {
|
||||
def b0 = Build.get(globals: [a: 0])
|
||||
def b1 = Build.get(globals: [b: 1])
|
||||
def sum = b0 + b1
|
||||
assertEquals([a: 0, b: 1], sum.globals)
|
||||
}
|
||||
|
||||
@Test
|
||||
void taskFactorySpecsAdded(@Mock Supplier<TaskFactory> taskFactorySupplier) {
|
||||
def spec0 = new TaskFactorySpec<>('spec0', taskFactorySupplier, [])
|
||||
def spec1 = new TaskFactorySpec<>('spec1', taskFactorySupplier, [])
|
||||
def b0 = Build.get(taskFactorySpecs: [spec0])
|
||||
def b1 = Build.get(taskFactorySpecs: [spec1])
|
||||
def sum = b0 + b1
|
||||
assertEquals([spec0, spec1], sum.taskFactorySpecs)
|
||||
}
|
||||
|
||||
}
|
@ -1,268 +0,0 @@
|
||||
package com.jessebrault.ssg.buildscript.delegates
|
||||
|
||||
import com.jessebrault.ssg.SiteSpec
|
||||
import com.jessebrault.ssg.buildscript.Build
|
||||
import com.jessebrault.ssg.buildscript.BuildIntermediate
|
||||
import com.jessebrault.ssg.buildscript.BuildMonoids
|
||||
import com.jessebrault.ssg.buildscript.BuildSpec
|
||||
import com.jessebrault.ssg.buildscript.OutputDir
|
||||
import com.jessebrault.ssg.buildscript.SourceProviders
|
||||
import com.jessebrault.ssg.buildscript.SyntheticBuildIntermediate
|
||||
import com.jessebrault.ssg.buildscript.TypesContainer
|
||||
import com.jessebrault.ssg.provider.CollectionProvider
|
||||
import com.jessebrault.ssg.provider.CollectionProviders
|
||||
import com.jessebrault.ssg.task.TaskFactory
|
||||
import com.jessebrault.ssg.task.TaskFactorySpec
|
||||
import com.jessebrault.ssg.text.Text
|
||||
import com.jessebrault.ssg.text.TextTypes
|
||||
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.Function
|
||||
import java.util.function.Supplier
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue
|
||||
|
||||
@ExtendWith(MockitoExtension)
|
||||
final class BuildDelegateTests {
|
||||
|
||||
private final BuildDelegate d = new BuildDelegate()
|
||||
|
||||
private BuildIntermediate getResults(BuildIntermediate parent = SyntheticBuildIntermediate.getEmpty()) {
|
||||
new BuildDelegate.BuildDelegateBuildIntermediate(
|
||||
BuildSpec.getEmpty(),
|
||||
this.d,
|
||||
parent,
|
||||
BuildMonoids.siteSpecMonoid,
|
||||
BuildMonoids.globalsMonoid,
|
||||
BuildMonoids.typesMonoid,
|
||||
BuildMonoids.sourcesMonoid,
|
||||
BuildMonoids.taskFactoriesMonoid,
|
||||
BuildMonoids.includedBuildsMonoid
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
void simpleOutputDirFunction(@Mock Function<Build, OutputDir> expected) {
|
||||
this.d.outputDirFunction = expected
|
||||
def r = this.getResults().outputDirFunction
|
||||
assertEquals(expected, r)
|
||||
}
|
||||
|
||||
@Test
|
||||
void mappedOutputDirFunction() {
|
||||
final Function<Build, OutputDir> base = { Build b ->
|
||||
new OutputDir('test')
|
||||
}
|
||||
this.d.outputDirFunction {
|
||||
it.andThen { new OutputDir(it.asString() + '/nested') }
|
||||
}
|
||||
def r = this.getResults(SyntheticBuildIntermediate.get(outputDirFunction: base))
|
||||
.outputDirFunction
|
||||
def outputDir = r.apply(Build.getEmpty())
|
||||
assertEquals('test/nested', outputDir.asString())
|
||||
}
|
||||
|
||||
@Test
|
||||
void siteSpecNoBase() {
|
||||
this.d.siteSpec {
|
||||
name = 'test'
|
||||
baseUrl = 'testUrl'
|
||||
}
|
||||
def r = this.getResults().siteSpec
|
||||
assertEquals('test', r.name)
|
||||
assertEquals('testUrl', r.baseUrl)
|
||||
}
|
||||
|
||||
@Test
|
||||
void mappedSiteSpec() {
|
||||
this.d.siteSpec { base ->
|
||||
name = base.name + 'Preview'
|
||||
baseUrl = base.baseUrl + '/preview'
|
||||
}
|
||||
def r = this.getResults(
|
||||
SyntheticBuildIntermediate.get(siteSpec: new SiteSpec('mySite', 'https://mysite.com'))
|
||||
).siteSpec
|
||||
assertEquals('mySitePreview', r.name)
|
||||
assertEquals('https://mysite.com/preview', r.baseUrl)
|
||||
}
|
||||
|
||||
@Test
|
||||
void siteSpecBaseConcat() {
|
||||
this.d.siteSpec {
|
||||
name = '123'
|
||||
}
|
||||
def r = this.getResults(
|
||||
SyntheticBuildIntermediate.get(siteSpec: new SiteSpec('', '456'))
|
||||
).siteSpec
|
||||
assertEquals('123', r.name)
|
||||
assertEquals('456', r.baseUrl)
|
||||
}
|
||||
|
||||
@Test
|
||||
void siteSpecBaseNoConcat() {
|
||||
this.d.siteSpec(false) {
|
||||
name = '123'
|
||||
}
|
||||
def r = this.getResults(
|
||||
SyntheticBuildIntermediate.get(siteSpec: new SiteSpec('', '456'))
|
||||
).siteSpec
|
||||
assertEquals('123', r.name)
|
||||
assertEquals(SiteSpec.DEFAULT_MONOID.zero.baseUrl, r.baseUrl)
|
||||
}
|
||||
|
||||
@Test
|
||||
void emptySiteSpec() {
|
||||
assertEquals(SiteSpec.getBlank(), this.getResults().siteSpec)
|
||||
}
|
||||
|
||||
@Test
|
||||
void globalsNoBase() {
|
||||
this.d.globals {
|
||||
test = 'abc'
|
||||
}
|
||||
def r = this.getResults().globals
|
||||
assertEquals([test: 'abc'], r)
|
||||
}
|
||||
|
||||
@Test
|
||||
void globalsWithBase() {
|
||||
this.d.globals { base ->
|
||||
test = base.test
|
||||
}
|
||||
def r = this.getResults(SyntheticBuildIntermediate.get(globals: [test: 'abc'])).globals
|
||||
assertEquals([test: 'abc'], r)
|
||||
}
|
||||
|
||||
@Test
|
||||
void globalsEmpty() {
|
||||
assertEquals([:], this.getResults().globals)
|
||||
}
|
||||
|
||||
@Test
|
||||
void typesNoBase() {
|
||||
this.d.types {
|
||||
textTypes << TextTypes.MARKDOWN
|
||||
}
|
||||
def r = this.getResults().types
|
||||
assertEquals(TypesContainer.get(textTypes: [TextTypes.MARKDOWN]), r)
|
||||
}
|
||||
|
||||
@Test
|
||||
void typesWithBaseNoConcat() {
|
||||
this.d.types(false) { base ->
|
||||
textTypes.addAll(base.textTypes)
|
||||
}
|
||||
def r = this.getResults(
|
||||
SyntheticBuildIntermediate.get(types: TypesContainer.get(textTypes: [TextTypes.MARKDOWN]))
|
||||
).types
|
||||
assertEquals(TypesContainer.get(textTypes: [TextTypes.MARKDOWN]), r)
|
||||
}
|
||||
|
||||
@Test
|
||||
void sourceProvidersNoBase(@Mock CollectionProvider<Text> textsProvider) {
|
||||
this.d.sources { base, types ->
|
||||
texts textsProvider
|
||||
}
|
||||
def r = this.getResults().sources
|
||||
assertTrue(textsProvider in r.textsProvider)
|
||||
}
|
||||
|
||||
// Cannot use Mockito for not yet understood reasons;
|
||||
// it seems that the mock is a part of an addition somewhere on the left side,
|
||||
// and because it doesn't have the method stubbed/mocked it
|
||||
// returns null. Why this confuses Groovy much later with
|
||||
// SourceProviders is not clear; perhaps because the mock
|
||||
// returns null, it throws an exception somewhere that is
|
||||
// swallowed?
|
||||
@Test
|
||||
void sourceProvidersWithBase(/* @Mock CollectionProvider<Text> textsProvider */) {
|
||||
def textsProvider = CollectionProviders.fromCollection([] as Collection<Text>)
|
||||
this.d.sources { base, types ->
|
||||
texts base.textsProvider
|
||||
}
|
||||
def r = this.getResults(
|
||||
SyntheticBuildIntermediate.get(sources: SourceProviders.get(textsProvider: textsProvider))
|
||||
).sources
|
||||
assertTrue(textsProvider in r.textsProvider)
|
||||
}
|
||||
|
||||
@Test
|
||||
void sourceProvidersMergeBase() {
|
||||
def textsProvider = CollectionProviders.fromCollection([] as Collection<Text>)
|
||||
def r = this.getResults(
|
||||
SyntheticBuildIntermediate.get(sources: SourceProviders.get(textsProvider: textsProvider))
|
||||
).sources
|
||||
assertTrue(textsProvider in r.textsProvider)
|
||||
}
|
||||
|
||||
@Test
|
||||
void taskFactoriesNoBase(@Mock Supplier<TaskFactory> taskFactorySupplier) {
|
||||
this.d.taskFactories { base, sources ->
|
||||
register('f0', taskFactorySupplier)
|
||||
}
|
||||
def r = this.getResults().taskFactorySpecs
|
||||
assertEquals(1, r.size())
|
||||
def spec0 = r[0]
|
||||
assertEquals('f0', spec0.name)
|
||||
assertEquals(taskFactorySupplier, spec0.supplier)
|
||||
}
|
||||
|
||||
@Test
|
||||
void taskFactoriesWithBase(@Mock Supplier<TaskFactory> taskFactorySupplier) {
|
||||
this.d.taskFactories(false) { base, sources ->
|
||||
registerAll(base)
|
||||
}
|
||||
def r = this.getResults(
|
||||
SyntheticBuildIntermediate.get(
|
||||
taskFactorySpecs: [new TaskFactorySpec<TaskFactory>('spec0', taskFactorySupplier, [])]
|
||||
)
|
||||
).taskFactorySpecs
|
||||
assertEquals(1, r.size())
|
||||
def spec0 = r[0]
|
||||
assertEquals('spec0', spec0.name)
|
||||
assertEquals(taskFactorySupplier, spec0.supplier)
|
||||
assertEquals([], spec0.configurators)
|
||||
}
|
||||
|
||||
@Test
|
||||
void taskFactoriesMergeBase(@Mock Supplier<TaskFactory> taskFactorySupplier) {
|
||||
def r = this.getResults(
|
||||
SyntheticBuildIntermediate.get(
|
||||
taskFactorySpecs: [new TaskFactorySpec<TaskFactory>('spec0', taskFactorySupplier, [])]
|
||||
)
|
||||
).taskFactorySpecs
|
||||
assertEquals(1, r.size())
|
||||
def spec0 = r[0]
|
||||
assertEquals('spec0', spec0.name)
|
||||
assertEquals(taskFactorySupplier, spec0.supplier)
|
||||
assertEquals([], spec0.configurators)
|
||||
}
|
||||
|
||||
@Test
|
||||
void includedBuildsNoBase() {
|
||||
this.d.concatIncludedBuildsWithBase = false
|
||||
this.d.includeBuild('included')
|
||||
def r = this.getResults(
|
||||
SyntheticBuildIntermediate.get(includedBuilds: ['notIncluded'])
|
||||
).includedBuilds
|
||||
assertEquals(1, r.size())
|
||||
def includedBuild0 = r[0]
|
||||
assertEquals('included', includedBuild0)
|
||||
}
|
||||
|
||||
@Test
|
||||
void includedBuildsWithBase() {
|
||||
this.d.concatIncludedBuildsWithBase = true
|
||||
def r = this.getResults(
|
||||
SyntheticBuildIntermediate.get(includedBuilds: ['baseIncluded'])
|
||||
).includedBuilds
|
||||
assertEquals(1, r.size())
|
||||
def includedBuild0 = r[0]
|
||||
assertEquals('baseIncluded', includedBuild0)
|
||||
}
|
||||
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package com.jessebrault.ssg.buildscript.delegates
|
||||
|
||||
import com.jessebrault.ssg.SiteSpec
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows
|
||||
|
||||
final class SiteSpecDelegateTests {
|
||||
|
||||
@Test
|
||||
void nullNotAllowed() {
|
||||
def d = new SiteSpecDelegate(SiteSpec.DEFAULT_MONOID)
|
||||
assertThrows(NullPointerException, {
|
||||
d.name = null
|
||||
})
|
||||
}
|
||||
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
package com.jessebrault.ssg.buildscript.delegates
|
||||
|
||||
import com.jessebrault.ssg.task.TaskFactory
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.extension.ExtendWith
|
||||
import org.junit.jupiter.api.function.Executable
|
||||
import org.mockito.Mock
|
||||
import org.mockito.junit.jupiter.MockitoExtension
|
||||
|
||||
import java.util.function.Consumer
|
||||
import java.util.function.Supplier
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*
|
||||
|
||||
@ExtendWith(MockitoExtension)
|
||||
final class TaskFactoriesDelegateTests {
|
||||
|
||||
@Test
|
||||
void registerThenConfigure(
|
||||
@Mock Supplier<TaskFactory> taskFactorySupplier,
|
||||
@Mock Consumer<TaskFactory> taskFactoryConsumer
|
||||
) {
|
||||
def d = new TaskFactoriesDelegate()
|
||||
d.register('test', taskFactorySupplier)
|
||||
assertDoesNotThrow({
|
||||
d.configure('test', TaskFactory, taskFactoryConsumer)
|
||||
} as Executable)
|
||||
def result = d.getResult()
|
||||
def testSpec = result.find { it.name == 'test' }
|
||||
assertNotNull(testSpec)
|
||||
assertEquals(taskFactorySupplier, testSpec.supplier)
|
||||
assertTrue(testSpec.configurators.contains(taskFactoryConsumer))
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerAndConfigure(
|
||||
@Mock Supplier<TaskFactory> taskFactorySupplier,
|
||||
@Mock Consumer<TaskFactory> taskFactoryConsumer
|
||||
) {
|
||||
def d = new TaskFactoriesDelegate()
|
||||
d.register('test', taskFactorySupplier, taskFactoryConsumer)
|
||||
def result = d.getResult()
|
||||
def testSpec = result.find { it.name == 'test' }
|
||||
assertNotNull(testSpec)
|
||||
assertEquals(taskFactorySupplier, testSpec.supplier)
|
||||
assertTrue(testSpec.configurators.contains(taskFactoryConsumer))
|
||||
}
|
||||
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
package com.jessebrault.ssg.mutable
|
||||
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue
|
||||
|
||||
final class SimpleMutableTests {
|
||||
|
||||
@Test
|
||||
void set() {
|
||||
final Mutable<String> p = Mutables.getEmpty()
|
||||
p.set('test')
|
||||
assertEquals('test', p.get())
|
||||
}
|
||||
|
||||
@Test
|
||||
void unset() {
|
||||
final Mutable<String> p = Mutables.getEmpty()
|
||||
p.set('test')
|
||||
p.unset()
|
||||
assertThrows(NullPointerException, p.&get)
|
||||
}
|
||||
|
||||
@Test
|
||||
void mapInPlace() {
|
||||
final Mutable<String> p = Mutables.getEmpty()
|
||||
p.set('abc')
|
||||
p.mapInPlace { it + 'def' }
|
||||
assertEquals('abcdef', p.get())
|
||||
}
|
||||
|
||||
@Test
|
||||
void filterInPlace() {
|
||||
final Mutable<String> p = Mutables.getEmpty()
|
||||
p.set('abc')
|
||||
p.filterInPlace { it.startsWith('z') }
|
||||
assertTrue(p.isEmpty())
|
||||
}
|
||||
|
||||
@Test
|
||||
void matchEmpty() {
|
||||
final Mutable<String> p = Mutables.getEmpty()
|
||||
def matched = p.match(
|
||||
() -> 'a',
|
||||
{ it + 'z' }
|
||||
)
|
||||
assertEquals('a', matched)
|
||||
}
|
||||
|
||||
@Test
|
||||
void matchPresent() {
|
||||
final Mutable<String> p = Mutables.getEmpty()
|
||||
p.set('a')
|
||||
def matched = p.match(
|
||||
() -> 'a',
|
||||
{it + 'z' }
|
||||
)
|
||||
assertEquals('az', matched)
|
||||
}
|
||||
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
package com.jessebrault.ssg.provider
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue
|
||||
|
||||
final class FileBasedCollectionProviderTests extends AbstractCollectionProviderTests {
|
||||
|
||||
@Override
|
||||
protected CollectionProvider<Integer> getCollectionProvider(Collection<Integer> ts) {
|
||||
def baseDir = File.createTempDir()
|
||||
new FileTreeBuilder(baseDir).tap {
|
||||
ts.each {
|
||||
file(it.toString(), '')
|
||||
}
|
||||
}
|
||||
new FileBasedCollectionProvider<>(baseDir, { File file, String relativePath ->
|
||||
logger.debug('file: {}, relativePath: {}', file, relativePath)
|
||||
def r = Integer.valueOf(relativePath)
|
||||
logger.debug('r: {}', r)
|
||||
r
|
||||
})
|
||||
}
|
||||
|
||||
@Test
|
||||
void containsSelfType() {
|
||||
def p = new FileBasedCollectionProvider<String>(new File(''), { f -> '' })
|
||||
assertTrue(p.containsType(DirectoryCollectionProvider))
|
||||
}
|
||||
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
package com.jessebrault.ssg.provider
|
||||
|
||||
final class SimpleCollectionProviderTests extends AbstractCollectionProviderTests {
|
||||
|
||||
@Override
|
||||
protected CollectionProvider<Integer> getCollectionProvider(Collection<Integer> ts) {
|
||||
new SimpleCollectionProvider<>(ts)
|
||||
}
|
||||
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
package com.jessebrault.ssg.provider
|
||||
|
||||
final class SupplierBaseCollectionProviderTests extends AbstractCollectionProviderTests {
|
||||
|
||||
@Override
|
||||
protected CollectionProvider<Integer> getCollectionProvider(Collection<Integer> ts) {
|
||||
new SupplierBasedCollectionProvider<Integer>({ ts })
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import com.jessebrault.ssg.buildscript.Build
|
||||
import com.jessebrault.ssg.buildscript.BuildSpec
|
||||
import com.jessebrault.ssg.buildscript.BuildScriptBase
|
||||
import com.jessebrault.ssg.buildscript.OutputDir
|
||||
import com.jessebrault.ssg.html.TextToHtmlSpecProviders
|
||||
@ -22,7 +22,7 @@ final class Args {
|
||||
def args = args as Args
|
||||
|
||||
build(name: 'test') {
|
||||
outputDirFunction = { Build build -> new OutputDir(new File(args.sourceDir, 'build')) }
|
||||
outputDirFunction = { BuildSpec build -> new OutputDir(new File(args.sourceDir, 'build')) }
|
||||
|
||||
types {
|
||||
textTypes << TextTypes.MARKDOWN
|
||||
|
@ -1,112 +0,0 @@
|
||||
package com.jessebrault.ssg.provider
|
||||
|
||||
import org.junit.jupiter.api.DynamicTest
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestFactory
|
||||
import org.mockito.Answers
|
||||
import org.mockito.Mockito
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
import java.util.function.Consumer
|
||||
|
||||
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
|
||||
|
||||
abstract class AbstractCollectionProviderTests {
|
||||
|
||||
protected static final Logger logger = LoggerFactory.getLogger(AbstractCollectionProviderTests)
|
||||
|
||||
protected abstract CollectionProvider<Integer> getCollectionProvider(Collection<Integer> ts)
|
||||
|
||||
@Test
|
||||
void providesTs() {
|
||||
def ts = [0, 1]
|
||||
def result = this.getCollectionProvider(ts).provide()
|
||||
logger.debug('result: {}', result)
|
||||
assertTrue(result.size() == 2)
|
||||
assertTrue(result.inject(true) { acc, val ->
|
||||
acc && ts.contains(val)
|
||||
})
|
||||
}
|
||||
|
||||
@Test
|
||||
void collectionsAdded() {
|
||||
def ts0 = [0, 1]
|
||||
def ts1 = [2, 3]
|
||||
def allTs = ts0 + ts1
|
||||
def p0 = this.getCollectionProvider(ts0)
|
||||
def p1 = this.getCollectionProvider(ts1)
|
||||
def sum = p0 + p1
|
||||
def result = sum.provide()
|
||||
logger.debug('result: {}', result)
|
||||
assertTrue(result.size() == 4)
|
||||
assertTrue(result.inject(true) { acc, val ->
|
||||
acc && allTs.contains(val)
|
||||
})
|
||||
}
|
||||
|
||||
@TestFactory
|
||||
Collection<DynamicTest> containsAndIsCaseCollectionProviderChildren() {
|
||||
def p0 = this.getCollectionProvider([])
|
||||
def p1 = this.getCollectionProvider([])
|
||||
def sum = p0 + p1
|
||||
([
|
||||
contains: { CollectionProvider<Integer> p ->
|
||||
assertTrue(p.contains(p0))
|
||||
assertTrue(p.contains(p1))
|
||||
} as Consumer<CollectionProvider<Integer>>,
|
||||
in: { CollectionProvider<Integer> p ->
|
||||
assertTrue(p0 in p)
|
||||
assertTrue(p1 in p)
|
||||
} as Consumer<CollectionProvider<Integer>>
|
||||
]).collect { entry ->
|
||||
DynamicTest.dynamicTest(entry.key, { entry.value.accept(sum) })
|
||||
}
|
||||
}
|
||||
|
||||
@TestFactory
|
||||
Collection<DynamicTest> containsAndIsCaseProviderChildren() {
|
||||
def p1 = this.getCollectionProvider([])
|
||||
def sum = p0 + p1
|
||||
([
|
||||
contains: { CollectionProvider<Integer> p ->
|
||||
assertTrue(p.contains(p1))
|
||||
} as Consumer<CollectionProvider<Integer>>,
|
||||
in: { CollectionProvider<Integer> p ->
|
||||
assertTrue(p0 in p)
|
||||
assertTrue(p1 in p)
|
||||
} as Consumer<CollectionProvider<Integer>>
|
||||
]).collect { entry ->
|
||||
DynamicTest.dynamicTest(entry.key, { entry.value.accept(sum) })
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void containsDirectoryCollectionProvider() {
|
||||
final CollectionProvider<Integer> dirProvider = CollectionProviders.fromDirectory(
|
||||
new File(''),
|
||||
{ 0 }
|
||||
)
|
||||
final CollectionProvider<Integer> dummy = CollectionProviders.getEmpty()
|
||||
def sum = dirProvider + dummy
|
||||
assertTrue(sum.containsType(DirectoryCollectionProvider))
|
||||
}
|
||||
|
||||
@Test
|
||||
void getDirectoryCollectionProviderChild() {
|
||||
final CollectionProvider<Integer> dirProvider = CollectionProviders.fromDirectory(
|
||||
new File(''),
|
||||
{ 0 }
|
||||
)
|
||||
final CollectionProvider<Integer> dummy = CollectionProviders.getEmpty()
|
||||
def sum = dirProvider + dummy
|
||||
def children =
|
||||
sum.<DirectoryCollectionProvider<Integer>>getChildrenOfType(DirectoryCollectionProvider)
|
||||
assertTrue(dirProvider in children)
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user