Testing various buildscript dsl delegates; CollectionProviders now have contain/isCase methods.

This commit is contained in:
JesseBrault0709 2023-04-28 09:14:26 +02:00
parent 334fa655dd
commit ced050b793
12 changed files with 277 additions and 25 deletions

View File

@ -22,7 +22,8 @@ abstract class AbstractBuildDelegate<T> {
this.siteSpecClosures.inject(SiteSpec.getBlank()) { acc, closure ->
def d = new SiteSpecDelegate()
closure.delegate = d
closure.resolveStrategy = DELEGATE_FIRST
//noinspection UnnecessaryQualifiedReference
closure.resolveStrategy = Closure.DELEGATE_FIRST
closure()
acc + d.getResult()
}
@ -32,7 +33,8 @@ abstract class AbstractBuildDelegate<T> {
this.globalsClosures.inject([:] as Map<String, Object>) { acc, closure ->
def d = new GlobalsDelegate()
closure.delegate = d
closure.resolveStrategy = DELEGATE_FIRST
//noinspection UnnecessaryQualifiedReference
closure.resolveStrategy = Closure.DELEGATE_FIRST
closure()
acc + d.getResult()
}
@ -42,7 +44,8 @@ abstract class AbstractBuildDelegate<T> {
this.typesClosures.inject(TypesContainer.getEmpty()) { acc, closure ->
def d = new TypesDelegate()
closure.delegate = d
closure.resolveStrategy = DELEGATE_FIRST
//noinspection UnnecessaryQualifiedReference
closure.resolveStrategy = Closure.DELEGATE_FIRST
closure()
acc + d.getResult()
}
@ -52,7 +55,8 @@ abstract class AbstractBuildDelegate<T> {
this.sourcesClosures.inject(SourceProviders.getEmpty()) { acc, closure ->
def d = new SourceProvidersDelegate()
closure.delegate = d
closure.resolveStrategy = DELEGATE_FIRST
//noinspection UnnecessaryQualifiedReference
closure.resolveStrategy = Closure.DELEGATE_FIRST
closure(typesContainer)
acc + d.getResult()
}
@ -62,7 +66,8 @@ abstract class AbstractBuildDelegate<T> {
this.taskFactoriesClosures.inject([:] as Map<String, TaskFactorySpec>) { acc, closure ->
def d = new TaskFactoriesDelegate()
closure.delegate = d
closure.resolveStrategy = DELEGATE_FIRST
//noinspection UnnecessaryQualifiedReference
closure.resolveStrategy = Closure.DELEGATE_FIRST
closure(sourceProviders)
def specs = d.getResult()
specs.forEach { name, spec ->

View File

@ -30,7 +30,11 @@ final class TaskFactoriesDelegate {
this.specs[name] = new TaskFactorySpec<>(factorySupplier, [factoryConfigurator])
}
def <T extends TaskFactory> void configure(String name, Class<T> factoryClass, Consumer<T> factoryConfigureClosure) {
def <T extends TaskFactory> void configure(
String name,
Class<T> factoryClass, // Dummy so we get better auto-complete
Consumer<T> factoryConfigureClosure
) {
if (!this.specs.containsKey(name)) {
throw new IllegalArgumentException("there is no TaskFactory registered by name ${ name }")
}

View File

@ -1,19 +1,48 @@
package com.jessebrault.ssg.provider
import groovy.transform.EqualsAndHashCode
import groovy.transform.NullCheck
import groovy.transform.TupleConstructor
@TupleConstructor(defaults = false, includeFields = true)
@NullCheck(includeGenerated = true)
@EqualsAndHashCode(includeFields = true)
abstract class AbstractCollectionProvider<T> implements CollectionProvider<T> {
static <T> CollectionProvider<T> concat(
CollectionProvider<T> cp,
Provider<T> p
) {
new SupplierBasedCollectionProvider<>([cp], [p], {
[*cp.provide(), p.provide()]
})
}
static <T> CollectionProvider<T> concat(
CollectionProvider<T> cp0,
CollectionProvider<T> cp1
) {
SupplierBasedCollectionProvider.get {
new SupplierBasedCollectionProvider<>([cp0, cp1], [], {
cp0.provide() + cp1.provide()
}
})
}
private final Collection<CollectionProvider<T>> collectionProviderChildren
private final Collection<Provider<T>> providerChildren
@Override
boolean contains(Provider<T> provider) {
provider in this
}
@Override
boolean contains(CollectionProvider<T> collectionProvider) {
collectionProvider in this
}
@Override
CollectionProvider<T> plus(Provider<T> other) {
concat(this, other as CollectionProvider<T>)
concat(this, other)
}
@Override
@ -21,4 +50,23 @@ abstract class AbstractCollectionProvider<T> implements CollectionProvider<T> {
concat(this, other)
}
@Override
boolean isCase(Provider<T> provider) {
provider in this.providerChildren || this.providerChildren.inject(false) { acc, childProvider ->
acc || provider in childProvider
}
}
@Override
boolean isCase(CollectionProvider<T> collectionProvider) {
collectionProvider == this
|| collectionProvider in this.collectionProviderChildren
|| this.collectionProviderChildren.inject(
false,
{ acc, childCollectionProvider ->
acc || collectionProvider in childCollectionProvider
}
)
}
}

View File

@ -6,9 +6,9 @@ abstract class AbstractProvider<T> implements Provider<T> {
Provider<T> p0,
Provider<T> p1
) {
SupplierBasedCollectionProvider.get {
new SupplierBasedCollectionProvider<>({
[p0.provide(), p1.provide()]
}
})
}
@Override
@ -18,9 +18,9 @@ abstract class AbstractProvider<T> implements Provider<T> {
@Override
CollectionProvider<T> asType(Class<CollectionProvider> collectionProviderClass) {
SupplierBasedCollectionProvider.get {
new SupplierBasedCollectionProvider<>({
[this.provide() as T]
}
})
}
}

View File

@ -2,6 +2,13 @@ package com.jessebrault.ssg.provider
interface CollectionProvider<T> {
Collection<T> provide()
boolean contains(Provider<T> provider)
boolean contains(CollectionProvider<T> collectionProvider)
CollectionProvider<T> plus(Provider<T> other)
CollectionProvider<T> plus(CollectionProvider<T> other)
boolean isCase(Provider<T> provider)
boolean isCase(CollectionProvider<T> collectionProvider)
}

View File

@ -5,7 +5,6 @@ import groovy.io.FileType
import groovy.transform.EqualsAndHashCode
import groovy.transform.NullCheck
import groovy.transform.PackageScope
import groovy.transform.TupleConstructor
import org.jetbrains.annotations.Nullable
import org.slf4j.Logger
import org.slf4j.LoggerFactory
@ -13,9 +12,8 @@ import org.slf4j.LoggerFactory
import java.util.function.BiFunction
@PackageScope
@TupleConstructor(includeFields = true, defaults = false)
@NullCheck(includeGenerated = true)
@EqualsAndHashCode(includeFields = true)
@NullCheck
@EqualsAndHashCode(includeFields = true, callSuper = true)
final class FileBasedCollectionProvider<T> extends AbstractCollectionProvider<T> {
private static final Logger logger = LoggerFactory.getLogger(FileBasedCollectionProvider)
@ -23,6 +21,12 @@ final class FileBasedCollectionProvider<T> extends AbstractCollectionProvider<T>
private final File baseDirectory
private final BiFunction<File, String, @Nullable T> elementFunction
FileBasedCollectionProvider(File baseDirectory, BiFunction<File, String, T> elementFunction) {
super([], [])
this.baseDirectory = baseDirectory
this.elementFunction = elementFunction
}
@Override
Collection<T> provide() {
if (!this.baseDirectory.isDirectory()) {

View File

@ -3,16 +3,19 @@ package com.jessebrault.ssg.provider
import groovy.transform.EqualsAndHashCode
import groovy.transform.NullCheck
import groovy.transform.PackageScope
import groovy.transform.TupleConstructor
@PackageScope
@TupleConstructor(defaults = false, includeFields = true)
@NullCheck(includeGenerated = true)
@EqualsAndHashCode(includeFields = true)
@NullCheck
@EqualsAndHashCode(includeFields = true, callSuper = true)
final class SimpleCollectionProvider<T> extends AbstractCollectionProvider<T> {
private final Collection<T> ts
SimpleCollectionProvider(Collection<T> ts) {
super([], [])
this.ts = ts
}
@Override
Collection<T> provide() {
this.ts

View File

@ -3,18 +3,29 @@ package com.jessebrault.ssg.provider
import groovy.transform.EqualsAndHashCode
import groovy.transform.NullCheck
import groovy.transform.PackageScope
import groovy.transform.TupleConstructor
import java.util.function.Supplier
@PackageScope
@TupleConstructor(defaults = false, includeFields = true)
@NullCheck(includeGenerated = true)
@EqualsAndHashCode(includeFields = true)
@NullCheck
@EqualsAndHashCode(includeFields = true, callSuper = true)
final class SupplierBasedCollectionProvider<T> extends AbstractCollectionProvider<T> {
private final Supplier<Collection<T>> supplier
SupplierBasedCollectionProvider(
Collection<CollectionProvider<T>> collectionProviderChildren,
Collection<Provider<T>> providerChildren,
Supplier<Collection<T>> supplier
) {
super(collectionProviderChildren, providerChildren)
this.supplier = supplier
}
SupplierBasedCollectionProvider(Supplier<Collection<T>> supplier) {
this([], [], supplier)
}
@Override
Collection<T> provide() {
this.supplier.get()

View File

@ -0,0 +1,97 @@
package com.jessebrault.ssg.buildscript.dsl
import com.jessebrault.ssg.SiteSpec
import com.jessebrault.ssg.buildscript.SourceProviders
import com.jessebrault.ssg.buildscript.TypesContainer
import com.jessebrault.ssg.page.Page
import com.jessebrault.ssg.page.PageTypes
import com.jessebrault.ssg.provider.CollectionProvider
import com.jessebrault.ssg.task.TaskFactory
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.Supplier
import static org.junit.jupiter.api.Assertions.assertEquals
import static org.junit.jupiter.api.Assertions.assertTrue
@ExtendWith(MockitoExtension)
abstract class AbstractBuildDelegateTests<T> {
protected abstract AbstractBuildDelegate<T> getDelegate()
@Test
void siteSpecsAdded() {
def d = this.getDelegate()
d.siteSpec {
name = 'test'
}
d.siteSpec {
baseUrl = 'test'
}
def sum = d.getSiteSpecResult()
assertEquals(new SiteSpec('test', 'test'), sum)
}
@Test
void globalsAdded() {
def d = this.getDelegate()
d.globals {
a = 0
}
d.globals {
b = 1
}
def sum = d.getGlobalsResult()
assertEquals([a: 0, b: 1], sum)
}
@Test
void typesAdded() {
def d = this.getDelegate()
d.types {
textTypes << TextTypes.MARKDOWN
}
d.types {
pageTypes << PageTypes.GSP
}
def sum = d.getTypesResult()
assertTrue(TextTypes.MARKDOWN in sum.textTypes)
assertTrue(PageTypes.GSP in sum.pageTypes)
}
@Test
void sourcesAdded(@Mock CollectionProvider<Text> textsProvider, @Mock CollectionProvider<Page> pagesProvider) {
def d = this.getDelegate()
d.providers {
texts(textsProvider)
}
d.providers {
pages(pagesProvider)
}
def sum = d.getSourcesResult(TypesContainer.getEmpty())
assertTrue(textsProvider in sum.textsProvider)
assertTrue(pagesProvider in sum.pagesProvider)
}
@Test
void taskFactoriesAdded(@Mock Supplier<TaskFactory> taskFactorySupplier) {
def d = this.getDelegate()
d.taskFactories {
register('tf0', taskFactorySupplier)
}
d.taskFactories {
register('tf1', taskFactorySupplier)
}
def sum = d.getTaskFactoriesResult(SourceProviders.getEmpty())
assertEquals(2, sum.size())
assertTrue(sum.inject(true) { acc, spec ->
acc && spec.supplier == taskFactorySupplier
})
}
}

View File

@ -0,0 +1,12 @@
package com.jessebrault.ssg.buildscript.dsl
import com.jessebrault.ssg.buildscript.Build
final class AllBuildsDelegateTests extends AbstractBuildDelegateTests<Build.AllBuilds> {
@Override
protected AbstractBuildDelegate<Build.AllBuilds> getDelegate() {
new AllBuildsDelegate()
}
}

View File

@ -0,0 +1,12 @@
package com.jessebrault.ssg.buildscript.dsl
import com.jessebrault.ssg.buildscript.Build
final class BuildDelegateTests extends AbstractBuildDelegateTests<Build> {
@Override
protected AbstractBuildDelegate<Build> getDelegate() {
new BuildDelegate()
}
}

View File

@ -0,0 +1,49 @@
package com.jessebrault.ssg.buildscript.dsl
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.assertDoesNotThrow
import static org.junit.jupiter.api.Assertions.assertEquals
import static org.junit.jupiter.api.Assertions.assertTrue
@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()
assertTrue(result.containsKey('test'))
assertEquals(taskFactorySupplier, result['test'].supplier)
assertTrue(result['test'].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()
assertTrue(result.containsKey('test'))
assertEquals(taskFactorySupplier, result['test'].supplier)
assertTrue(result['test'].configurators.contains(taskFactoryConsumer))
}
}