blob: c9b2ab81bcaad0d2a97fc1fa31a75baccb7ab19b [file] [log] [blame]
package ioc.specs
import org.apache.tapestry5.ioc.internal.AlphabetModule
import org.apache.tapestry5.ioc.internal.AlphabetModule2
import org.apache.tapestry5.ioc.services.SymbolSource
import org.apache.tapestry5.ioc.util.NonmatchingMappedConfigurationOverrideModule
import org.apache.tapestry5.ioc.*
/** Integration tests for various types of service configurations. */
class ConfigurationsSpec extends AbstractRegistrySpecification {
def "all contributions to unordered configuration are collected"() {
buildRegistry FredModule, BarneyModule
when:
def holder = getService "UnorderedNames", NameListHolder
then:
// We don't know the actual contribution order, the impl sorts them. Just
// check they are all present.
holder.names == ["Beta", "Gamma", "UnorderedNames"]
}
def "all contributions to order configuration are collected"() {
buildRegistry FredModule, BarneyModule
when:
def holder = getService "OrderedNames", NameListHolder
then:
holder.names == ["BARNEY", "FRED"]
}
def "all contribution to mapped configuration are collected"() {
buildRegistry FredModule, BarneyModule
def sizer = getService "Sizer", Sizer
expect:
// The contributions map different Classes to strategies; this demonstrates
// that all contributions have been mapped and provided to Sizer service impl.
sizer.size(null) == 0
sizer.size([1, 2, 3]) == 3
sizer.size([fred: "flintstone", barney: "rubble"]) == 2
sizer.size(this) == 1
}
def "can contribute a class to an unordered configuration"() {
buildRegistry ContributeByClassModule
when:
def tx = getService "MasterStringTransformer", StringTransformer
then:
tx.transform("Tapestry") == "TAPESTRY"
}
def "can contribute a class to an ordered configuration"() {
buildRegistry ContributeByClassModule
when:
def tx = getService "StringTransformerChain", StringTransformer
then:
tx.transform("Tapestry") == "TAPESTRY"
}
def "can contribute class to a mapped configuration"() {
buildRegistry ContributeByClassModule
when:
def tx = getService "MappedStringTransformer", StringTransformer
then:
tx.transform("Tapestry") == "TAPESTRY"
}
def "contribution to an unknown configuration is detected as an exception"() {
when:
buildRegistry InvalidContributeDefModule
then:
IllegalArgumentException e = thrown()
e.message.contains "Contribution org.apache.tapestry5.ioc.InvalidContributeDefModule.contributeDoesNotExist(Configuration)"
e.message.contains "is for service 'DoesNotExist', which does not exist."
}
def "a value in an ordered configuration may be overridden"() {
buildRegistry FredModule, BarneyModule, ConfigurationOverrideModule
when:
def holder = getService "OrderedNames", NameListHolder
then:
holder.names == ["BARNEY", "WILMA", "Mr. Flintstone"]
}
def "an override value in an ordered configuration must match a normally contributed value"() {
buildRegistry FredModule, BarneyModule, FailedConfigurationOverrideModule
def holder = getService "OrderedNames", NameListHolder
when:
holder.names
then:
RuntimeException e = thrown()
e.message.contains "Failure processing override from org.apache.tapestry5.ioc.FailedConfigurationOverrideModule.contributeOrderedNames(OrderedConfiguration)"
e.message.contains "Override for object 'wilma' is invalid as it does not match an existing object."
}
def "a contribution to an ordered configuration may only be overridden once"() {
buildRegistry FredModule, BarneyModule, ConfigurationOverrideModule, DuplicateConfigurationOverrideModule
def holder = getService "OrderedNames", NameListHolder
when:
holder.names
then:
RuntimeException e = thrown()
e.message.contains "Error invoking service contribution method"
e.message.contains "Contribution 'fred' has already been overridden"
}
def "contributions to mapped configurations may be overridden"() {
buildRegistry FredModule, BarneyModule, ConfigurationOverrideModule
when:
def sl = getService StringLookup
then:
sl.keys() == ["barney", "betty", "fred"]
sl.lookup("fred") == "Mr. Flintstone"
}
def "mapped configuration overrides must match an existing value"() {
buildRegistry FredModule, BarneyModule, NonmatchingMappedConfigurationOverrideModule
def sl = getService StringLookup
when:
sl.keys()
then:
RuntimeException e = thrown()
e.message.contains "Override for key alley cat (at org.apache.tapestry5.ioc.util.NonmatchingMappedConfigurationOverrideModule.contributeStringLookup(MappedConfiguration)"
e.message.contains "does not match an existing key"
}
def "a contribution to a mapped configuration may only be overridden once"() {
buildRegistry FredModule, BarneyModule, ConfigurationOverrideModule, DuplicateConfigurationOverrideModule
def sl = getService StringLookup
when:
sl.keys()
then:
RuntimeException e = thrown()
e.message.contains "Error invoking service contribution method"
e.message.contains "Contribution key fred has already been overridden"
}
def "support for @Contribute annotation"() {
buildRegistry AlphabetModule, AlphabetModule2
when:
def greek = getService "Greek", NameListHolder
then:
greek.names == ["Alpha", "Beta", "Gamma", "Delta"]
when:
def anotherGreek = getService "AnotherGreek", NameListHolder
then:
anotherGreek.names == ["Alpha", "Beta", "Gamma", "Delta", "Epsilon"]
when:
def hebrew = getService "Hebrew", NameListHolder
then:
hebrew.names == ["Alef", "Bet", "Gimel", "Dalet", "He", "Vav"]
when:
def holder = getService "ServiceWithEmptyConfiguration", NameListHolder2
then:
holder.names.empty
}
def "contribute by @Contribute annotation to non-existent service"() {
when:
buildRegistry InvalidContributeDefModule2
then:
RuntimeException e = thrown()
["Contribution org.apache.tapestry5.ioc.InvalidContributeDefModule2.provideConfiguration(OrderedConfiguration)",
"is for service 'interface org.apache.tapestry5.ioc.NameListHolder'",
"qualified with marker annotations [",
"interface org.apache.tapestry5.ioc.BlueMarker",
"interface org.apache.tapestry5.ioc.RedMarker",
"], which does not exist."].every { e.message.contains it}
}
def "contribute using @Contribute using invalid marker annotation is an exception"() {
when:
buildRegistry InvalidContributeDefModule3
then:
RuntimeException e = thrown()
["Contribution org.apache.tapestry5.ioc.InvalidContributeDefModule3.provideConfiguration(OrderedConfiguration)",
"is for service 'interface org.apache.tapestry5.ioc.NameListHolder'",
"qualified with marker annotations [interface org.apache.tapestry5.ioc.BlueMarker], which does not exist."].every
{ e.message.contains it}
}
def "ServiceResources are available to contribution methods"() {
buildRegistry InjectionCheckModule
when:
def s = getService InjectionCheck
def il = s.getValue "indirect-resources"
then:
s.logger.is(s.getValue("logger"))
s.logger.is il.logger
s.logger.is il.resources.logger
}
def "service id in contribute method is matched caselessly"() {
buildRegistry CaseInsensitiveContributeMethodModule
when:
def ss = getService SymbolSource
then:
ss.valueForSymbol("it") == "works"
}
def "contributed values may be coerced to the correct type"() {
buildRegistry ContributedValueCoercionModule
when:
def ss = getService SymbolSource
then:
ss.valueForSymbol("bool-true") == "true"
ss.valueForSymbol("bool-false") == "false"
ss.valueForSymbol("num-12345") == "12345"
}
def "@Optional contribution to an unknown service is not an error"() {
when:
buildRegistry OptionalContributionModule
then:
noExceptionThrown()
}
// TAP5-2358
def "OrderedConfiguration should have consistent ordering"() {
when:
buildRegistry ContributionOrderModule, ContributionOrderModule2, ContributionOrderModule3, ContributionOrderModule4
def configuration1 = getService(OrderedService).getContributions();
buildRegistry ContributionOrderModule4, ContributionOrderModule3, ContributionOrderModule2, ContributionOrderModule
def configuration2 = getService(OrderedService).getContributions();
then:
configuration1.equals(configuration2)
}
}