To apply this plugin to a Gradle project, Gradle v6.0 or higher is recommended (although Gradle versions as low as v5.1 are compatible).
This plugin, when applied to a project, configures it as follows:
-
The Java Library and Groovy plugins are applied
-
Compatibility is set to Java 8
-
The Maven Central repository is added, as well as DFKI’s MLT repository (to resolve the JTok dependency)
-
Integration tests are set up via the
integrationTest
source set and task -
Testing is enabled using TestNG
Specifically for MaryTTS, additional classes and resources are generated and included in the main configuration classpath:
This plugin adds a marytts.component
extension, which is configured like this:
marytts {
component {
name = 'Hello' // (1)
packageName = 'my.world' // (2)
}
}
-
Custom component name
-
Custom package name
This will generate the config file, service loader, and boilerplate Groovy and Java source code to test and use, respectively, this component with MaryTTS:
build
├── generatedIntegrationTestSrc
│ └── my # (1)
│ └── world
│ └── LoadHelloIT.groovy # (2)
├── generatedSrc
│ └── my # (1)
│ └── world
│ └── HelloConfig.java # (2)
└── generatedTestSrc
└── my # (1)
└── world
└── HelloConfigTest.groovy # (2)
-
Custom package path
-
Class names derived from custom component name
Since many MaryTTS components require detailed configuration, the configuration can be externalized into a YAML resource, like this:
marytts {
component {
config from: 'config.yaml' // (1)
}
}
-
YAML config source
❗
|
If a YAML file is specified, it must be readable and valid, otherwise Gradle will fail to configure the project! |
# A comment
locale: xy
foo:
bar: foo baz # (1)
qux: # (2)
- quux
- quuux
fnord: 'jar:/path/to/the/fnord' # (3)
-
Nested config keys will be flattened.
-
A list will be converted to a config property with a trailing
.list
. -
A value with a
jar:
prefix (which should be quoted in YAML) will be treated as a classpath resource when the component runs in MaryTTS.
The above YAML config will generate a configuration like this:
locale = xy
foo.bar = foo baz
foo.qux.list = \
quux \
quuux
foo.fnord = jar:/path/to/the/fnord
Groovy source code for unit and integration testing with TestNG will be generated to verify that the component can be loaded, and that all configured properties have the expected values. Any resources will be loaded as streams to ensure they exist on the classpath.
package my.world
import marytts.config.*
import org.testng.annotations.*
class HelloConfigTest {
HelloConfig config
@BeforeMethod
void setup() {
config = new HelloConfig()
}
@Test
public void isNotMainConfig() {
assert config.isMainConfig() == false
}
@Test
public void testConfigBaseClass() {
assert config instanceof LanguageConfig
}
@Test
public void canGetProperties() { // (1)
assert config.properties.'locale' == 'xy'
assert config.properties.'foo.bar' == 'foo baz'
assert config.properties.'foo.qux.list'.tokenize().containsAll(['quux', 'quuux'])
assert config.properties.'foo.fnord' == 'jar:/path/to/the/fnord'
}
}
-
Assertions generated from config
package my.world
import marytts.server.MaryProperties
import marytts.util.MaryRuntimeUtils
import org.testng.annotations.*
class LoadHelloIT {
@BeforeMethod
void setup() {
MaryRuntimeUtils.ensureMaryStarted()
}
@DataProvider
Object[][] properties() {
[ // (1)
['foo.bar', 'foo baz'],
['foo.qux.list', ['quux', 'quuux']],
['foo.fnord', 'jar:/path/to/the/fnord']
]
}
@Test(dataProvider = 'properties')
public void canGetProperty(name, expected) {
def actual
switch (name) {
case ~/.+\.list$/:
actual = MaryProperties.getList(name)
assert actual.containsAll(expected)
break
default:
actual = MaryProperties.getProperty(name)
assert expected == actual
break
}
if ("$expected".startsWith('jar:')) {
assert MaryProperties.getStream(name)
}
}
}
-
Parameterized tests generated from config