You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2012/05/16 20:50:31 UTC
[18/44] git commit: Convert TestNG to Spock
Convert TestNG to Spock
Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/cf890643
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/cf890643
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/cf890643
Branch: refs/heads/master
Commit: cf89064355ece3f9a2392501649d0777a839923b
Parents: d49dd96
Author: Howard M. Lewis Ship <hl...@gmail.com>
Authored: Thu May 3 10:38:45 2012 -0700
Committer: Howard M. Lewis Ship <hl...@apache.org>
Committed: Wed May 16 11:50:13 2012 -0700
----------------------------------------------------------------------
.../org/apache/tapestry5/ioc/AdvisorsSpec.groovy | 83 +
.../org/apache/tapestry5/ioc/AutobuildSpec.groovy | 171 ++
.../apache/tapestry5/ioc/ConfigurationsSpec.groovy | 316 +++
.../org/apache/tapestry5/ioc/DecoratorsSpec.groovy | 109 +
.../org/apache/tapestry5/ioc/InjectionSpec.groovy | 123 ++
.../tapestry5/ioc/ManifestProcessingSpec.groovy | 36 +
.../tapestry5/ioc/ModuleInstantiationSpec.groovy | 52 +
.../apache/tapestry5/ioc/PerThreadScopeSpec.groovy | 88 +
.../tapestry5/ioc/RegistryBuilderSpec.groovy | 3 -
...RegistryConstructionAndRuntimeErrorsSpec.groovy | 117 +
.../org/apache/tapestry5/ioc/RegistrySpec.groovy | 53 +
.../ioc/ServiceActivityScoreboardSpec.groovy | 74 +
.../apache/tapestry5/ioc/ServiceBinderSpec.groovy | 35 +
.../apache/tapestry5/ioc/ServiceLookupSpec.groovy | 116 +
.../apache/tapestry5/ioc/ServiceProxySpec.groovy | 96 +
.../org/apache/tapestry5/ioc/BarneyModule.java | 180 +-
.../apache/tapestry5/ioc/CountingGreeterImpl.java | 4 +-
.../org/apache/tapestry5/ioc/IntegrationTest.java | 1629 ---------------
.../tapestry5/ioc/IntegrationTestFixture.java | 9 +
.../tapestry5/ioc/RecursiveConstructorModule.java | 5 +-
.../org/apache/tapestry5/ioc/StaticModule.java | 179 +-
.../apache/tapestry5/ioc/StringTransformer.java | 6 +-
22 files changed, 1652 insertions(+), 1832 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cf890643/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/AdvisorsSpec.groovy
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/AdvisorsSpec.groovy b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/AdvisorsSpec.groovy
new file mode 100644
index 0000000..d4abc93
--- /dev/null
+++ b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/AdvisorsSpec.groovy
@@ -0,0 +1,83 @@
+package org.apache.tapestry5.ioc
+
+import org.apache.tapestry5.ioc.internal.AdviseByMarkerModule
+import org.apache.tapestry5.ioc.internal.AdviseByMarkerModule2
+
+
+class AdvisorsSpec extends AbstractRegistrySpecification {
+
+ def "advisor methods must return void"() {
+ when:
+
+ buildRegistry NonVoidAdvisorMethodModule
+
+ then:
+
+ RuntimeException e = thrown()
+
+ e.message.contains "Advise method org.apache.tapestry5.ioc.NonVoidAdvisorMethodModule.adviseFoo(MethodAdviceReceiver)"
+ e.message.contains "does not return void"
+ }
+
+ def "advisor methods must take a MethodAdviceReceiver parameter"() {
+ when:
+
+ buildRegistry AdviceMethodMissingAdvisorParameterModule
+
+ then:
+
+ RuntimeException e = thrown()
+
+ e.message.contains "Advise method org.apache.tapestry5.ioc.AdviceMethodMissingAdvisorParameterModule.adviseBar()"
+ e.message.contains "must take a parameter of type org.apache.tapestry5.ioc.MethodAdviceReceiver."
+ }
+
+ def "adding advice to services"() {
+ buildRegistry AdviceDemoModule
+
+ when:
+
+ def g = getService Greeter
+
+ then:
+
+ g.greeting == "ADVICE IS EASY!"
+ }
+
+ def "methods marked with @Advise are advisor methods"() {
+
+ buildRegistry GreeterModule2, AdviseByMarkerModule
+
+ when:
+
+ def green = getService "GreenGreeter", Greeter
+
+ then:
+
+ green.greeting == "gamma[beta[alpha[Green]]]"
+ }
+
+ def "@Advise with @Local only advises services in the same module"() {
+ buildRegistry GreeterModule2, AdviseByMarkerModule
+
+ when:
+
+ def red = getService "RedGreeter", Greeter
+
+ then:
+
+ red.greeting == "delta[Red]"
+ }
+
+ def "@Advise with id attribute"() {
+ buildRegistry AdviseByMarkerModule2
+
+ when:
+
+ def red = getService "RedGreeter", Greeter
+
+ then:
+
+ red.greeting == "beta[alpha[Red]]"
+ }
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cf890643/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/AutobuildSpec.groovy
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/AutobuildSpec.groovy b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/AutobuildSpec.groovy
new file mode 100644
index 0000000..d5aa6a5
--- /dev/null
+++ b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/AutobuildSpec.groovy
@@ -0,0 +1,171 @@
+package org.apache.tapestry5.ioc
+
+import org.apache.tapestry5.ioc.internal.ExceptionInConstructorModule
+
+class AutobuildSpec extends AbstractRegistrySpecification {
+
+ def "ensure that services defined with bind() are automatically built"() {
+ buildRegistry AutobuildModule
+
+ def sh = getService StringHolder
+
+ when:
+
+ sh.value = "Foo"
+
+ then:
+
+ sh.value == "Foo"
+ }
+
+ def "check reporting of exception in autobuilt service constructor"() {
+ buildRegistry ExceptionInConstructorModule
+
+ def pingable = getService Pingable
+
+ when:
+
+ pingable.ping()
+
+ then:
+
+ RuntimeException e = thrown()
+
+ e.message.contains "Error invoking constructor"
+ e.message.contains "ExceptionInConstructorServiceImpl()"
+ e.message.contains "Yes, we have no tomatoes."
+ }
+
+ def "bind() finds the default Impl class"() {
+ buildRegistry ConventionModule
+
+ def holder = getService StringHolder
+
+ when:
+
+ // This proves we can invoke methods, meaning that an implementation was found.
+
+ holder.value = "Bar"
+
+ then:
+
+ holder.value == "Bar"
+ }
+
+ def "validate exception reporting for no default implementation found"() {
+ when:
+
+ buildRegistry ConventionModuleImplementationNotFound
+
+ then:
+
+ RuntimeException e = thrown()
+ e.message.contains "Could not find default implementation class org.apache.tapestry5.ioc.StringTransformerImpl."
+ e.message.contains "Please provide this class, or bind the service interface to a specific implementation class."
+ }
+
+ def "validate exception reporting for incorrect implementation (that does not implement service interface)"() {
+ when:
+
+ buildRegistry ConventionFailureModule
+
+ then:
+
+ RuntimeException e = thrown()
+
+ e.message.contains "No service implements the interface ${Pingable.name}"
+ }
+
+ def "service builder method can use ServiceResources.autobuild()"() {
+ buildRegistry ServiceBuilderAutobuilderModule
+
+ def holder = getService StringHolder
+
+ when:
+
+ holder.value = "Foo"
+
+ then:
+
+ holder.value == "Foo"
+ }
+
+ def "ensure that Registry.autobuild() works"() {
+
+ buildRegistry()
+
+ when:
+
+ def holder = autobuild StringHolderImpl
+
+ // This test should go further and verify that injections into StringHolderImpl work.
+
+ then:
+
+ holder.class == StringHolderImpl
+
+ when:
+
+ holder.value = "Foo"
+
+ then:
+
+ holder.value == "Foo"
+ }
+
+ def "ensure that Registry.autobuild() works (with a description)"() {
+ buildRegistry()
+
+ when:
+
+ def holder = autobuild "Building StringHolderImpl", StringHolderImpl
+
+ // This test should go further and verify that injections into StringHolderImpl work.
+
+ then:
+
+ holder.class == StringHolderImpl
+ }
+
+ def "verify exception when autobuild service implementation is not valid"() {
+ buildRegistry ServiceBuilderAutobuilderModule
+
+ def pingable = getService Pingable
+
+ when:
+
+ pingable.ping()
+
+ then:
+
+ RuntimeException e = thrown()
+
+ e.message.contains "Class org.apache.tapestry5.ioc.UnbuildablePingable does not contain a public constructor needed to autobuild."
+ }
+
+ def "verify exception when autobuild class has not valid constructor"() {
+ buildRegistry()
+
+ when:
+
+ autobuild UnbuildablePingable
+
+ then:
+
+ RuntimeException e = thrown()
+
+ e.message.contains "Class org.apache.tapestry5.ioc.UnbuildablePingable does not contain a public constructor needed to autobuild."
+ }
+
+ def "a service build method may include a parameter with @Autobuild"() {
+ buildRegistry AutobuildInjectionModule
+
+ when:
+
+ def tx = getService StringTransformer
+
+ then:
+
+ tx.transform('Hello, ${fred}') == "Hello, flintstone"
+ }
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cf890643/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/ConfigurationsSpec.groovy
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/ConfigurationsSpec.groovy b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/ConfigurationsSpec.groovy
new file mode 100644
index 0000000..d0db942
--- /dev/null
+++ b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/ConfigurationsSpec.groovy
@@ -0,0 +1,316 @@
+package org.apache.tapestry5.ioc
+
+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
+
+/** 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()
+ }
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cf890643/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/DecoratorsSpec.groovy
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/DecoratorsSpec.groovy b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/DecoratorsSpec.groovy
new file mode 100644
index 0000000..8dfa727
--- /dev/null
+++ b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/DecoratorsSpec.groovy
@@ -0,0 +1,109 @@
+package org.apache.tapestry5.ioc
+
+import org.apache.tapestry5.ioc.internal.DecorateByMarkerModule
+import org.apache.tapestry5.ioc.internal.DecorateByMarkerModule2
+
+/** Integration tests for service decorators and some related behaviors. */
+class DecoratorsSpec extends AbstractRegistrySpecification {
+
+ def "verify order of service decorators"() {
+ buildRegistry FredModule, BarneyModule
+
+ def fred = getService "Fred", Runnable
+ def list = getService DecoratorList
+
+ when:
+
+ fred.run()
+
+ then:
+
+ list.names == ["gamma", "beta", "alpha"]
+ }
+
+ def "decorators receive the delegate by the specific type"() {
+
+ buildRegistry GreeterModule, SpecificDecoratorModule
+
+ when:
+
+ def g = getService "HelloGreeter", Greeter
+
+ then:
+
+ g.greeting == "HELLO"
+ }
+
+ def "a service builder method with @PreventServiceDecoration is not decorated"() {
+ buildRegistry PreventDecorationModule
+
+ when:
+
+ def st = getService StringTransformer
+
+ then:
+
+ st.transform("tapestry") == "TAPESTRY"
+ }
+
+ def "Binding a service with explicit no decorations will ensure that the implementation is not decorated"() {
+ buildRegistry PreventDecorationModule
+
+ when:
+
+ def g = getService Greeter
+
+ then:
+
+ g.greeting == "Greetings from ServiceIdGreeter."
+ }
+
+ def "@PreventServiceDecoration on a service implementation class ensures that the implementation is not decorated"() {
+ buildRegistry PreventDecorationModule
+
+ when:
+
+ def rocket = getService Rocket
+
+ then:
+
+ rocket.countdown == "3, 2, 1, Launch!"
+ }
+
+ def "@Decorate marks a module method as a decorator method"() {
+ buildRegistry GreeterModule2, DecorateByMarkerModule
+
+ when:
+
+ def green = getService "GreenGreeter", Greeter
+
+ then:
+
+ green.greeting == "Decorated by foo[Decorated by baz[Decorated by bar[Green]]]"
+ }
+
+ def "@Decorate with @Local only decorates services from the same module"() {
+ buildRegistry GreeterModule2, DecorateByMarkerModule
+
+ when:
+
+ def red = getService "RedGreeter", Greeter
+
+ then:
+
+ red.greeting == "Decorated by barney[Red]"
+ }
+
+ def "@Decorate with id attribute"() {
+ buildRegistry DecorateByMarkerModule2
+
+ when:
+
+ def green = getService "RedGreeter", Greeter
+
+ then:
+
+ green.greeting == "Decorated by beta[Decorated by alpha[Red]]"
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cf890643/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/InjectionSpec.groovy
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/InjectionSpec.groovy b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/InjectionSpec.groovy
new file mode 100644
index 0000000..33650f9
--- /dev/null
+++ b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/InjectionSpec.groovy
@@ -0,0 +1,123 @@
+package org.apache.tapestry5.ioc
+
+
+class InjectionSpec extends AbstractRegistrySpecification {
+
+ def "symbol in @Inject is expanded"() {
+
+ buildRegistry GreeterModule
+
+ when:
+
+ def greeter = getService "Greeter", Greeter
+
+ then:
+
+ greeter.greeting == "Hello"
+ greeter.toString() == "<Proxy for Greeter(org.apache.tapestry5.ioc.Greeter)>"
+ }
+
+ def "injection by marker with single match"() {
+
+ buildRegistry GreeterModule
+
+ when:
+
+ def greeter = getService "InjectedBlueGreeter", Greeter
+
+ then:
+
+ greeter.greeting == "Blue"
+ }
+
+ def "verify exception for inject by marker with multiple matches"() {
+ buildRegistry GreeterModule
+
+ def greeter = getService "InjectedRedGreeter", Greeter
+
+ when:
+
+ greeter.greeting
+
+ then:
+
+ RuntimeException e = thrown()
+
+ e.message.contains "Unable to locate a single service assignable to type org.apache.tapestry5.ioc.Greeter with marker annotation(s) org.apache.tapestry5.ioc.RedMarker"
+ e.message.contains "org.apache.tapestry5.ioc.GreeterModule.buildRedGreeter1()"
+ e.message.contains "org.apache.tapestry5.ioc.GreeterModule.buildRedGreeter2()"
+ }
+
+ def "verify exception for injection by marker and no matches"() {
+ buildRegistry GreeterModule
+
+ def greeter = getService "InjectedYellowGreeter", Greeter
+
+ when:
+
+ greeter.greeting
+
+ then:
+
+ RuntimeException e = thrown()
+
+ e.message.contains "Exception constructing service"
+ e.message.contains "Unable to locate any service assignable to type org.apache.tapestry5.ioc.Greeter with marker annotation(s) org.apache.tapestry5.ioc.YellowMarker."
+ }
+
+ def "recursion handling injections (due to MasterObjectProvider) is detected"() {
+
+ buildRegistry CyclicMOPModule
+
+ def trigger = getService "Trigger", Runnable
+
+ when:
+
+ trigger.run()
+
+ then:
+
+ RuntimeException e = thrown()
+
+ e.message.contains "Construction of service 'TypeCoercer' has failed due to recursion"
+ }
+
+ def "A field may be annotated with @InjectResource to receive resources"() {
+
+ buildRegistry FieldResourceInjectionModule
+
+ when:
+
+ def s = getService FieldResourceService
+
+ then:
+
+ s.serviceId == "FieldResourceService"
+
+ s.labels == ["Barney", "Betty", "Fred", "Wilma"]
+ }
+
+ def "methods with @PostInjection are invoked and can be passed further injections"() {
+ buildRegistry PostInjectionMethodModule
+
+ when:
+
+ def g = getService Greeter
+
+ then:
+
+ g.greeting == "Greetings from ServiceIdGreeter."
+ }
+
+ def "a service may be overridden by contributing to ServiceOverride"() {
+ buildRegistry GreeterServiceOverrideModule
+
+ when:
+
+ def g = getObject Greeter, null
+
+ then:
+
+ g.greeting == "Override Greeting"
+ }
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cf890643/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/ManifestProcessingSpec.groovy
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/ManifestProcessingSpec.groovy b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/ManifestProcessingSpec.groovy
new file mode 100644
index 0000000..51b0949
--- /dev/null
+++ b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/ManifestProcessingSpec.groovy
@@ -0,0 +1,36 @@
+package org.apache.tapestry5.ioc
+
+import spock.lang.Specification
+
+
+class ManifestProcessingSpec extends Specification {
+
+ def "invalid class in manifest"() {
+
+ File fakejar = new File("src/test/fakejar")
+
+ expect:
+
+ // This is more to verify the module execution environment
+ fakejar.exists()
+ fakejar.isDirectory()
+
+ when:
+
+ URL url = fakejar.toURL()
+ URLClassLoader loader = new URLClassLoader([url] as URL[], Thread.currentThread().contextClassLoader)
+
+ RegistryBuilder builder = new RegistryBuilder(loader)
+
+ IOCUtilities.addDefaultModules(builder)
+
+ then:
+
+ RuntimeException e = thrown()
+
+ e.message.contains "Exception loading module(s) from manifest"
+ e.message.contains "Failure loading Tapestry IoC module class does.not.exist.Module"
+
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cf890643/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/ModuleInstantiationSpec.groovy
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/ModuleInstantiationSpec.groovy b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/ModuleInstantiationSpec.groovy
new file mode 100644
index 0000000..67c2fb3
--- /dev/null
+++ b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/ModuleInstantiationSpec.groovy
@@ -0,0 +1,52 @@
+package org.apache.tapestry5.ioc
+
+
+class ModuleInstantiationSpec extends AbstractRegistrySpecification {
+ def setup() {
+ StaticModule.reset()
+ }
+
+ def "module class is not instantiated when invoking static builder method"() {
+ buildRegistry StaticModule
+
+ def fred = getService "Fred", Runnable
+
+ when:
+
+ fred.run()
+
+ then:
+
+ !StaticModule.instantiated
+ StaticModule.fredRan
+ }
+
+ def "module class is not instantiated when invoking static decorator method"() {
+ buildRegistry StaticModule
+
+ def barney = getService "Barney", Runnable
+
+ when:
+
+ barney.run()
+
+ then:
+
+ !StaticModule.instantiated
+ StaticModule.decoratorRan
+ }
+
+ def "module class is not instantiated when invoking a static contributor method"() {
+ buildRegistry StaticModule
+
+ def holder = getService "Names", NameListHolder
+
+ when:
+
+ assert holder.names == ["Fred"]
+
+ then:
+
+ !StaticModule.instantiated
+ }
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cf890643/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/PerThreadScopeSpec.groovy
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/PerThreadScopeSpec.groovy b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/PerThreadScopeSpec.groovy
new file mode 100644
index 0000000..9533862
--- /dev/null
+++ b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/PerThreadScopeSpec.groovy
@@ -0,0 +1,88 @@
+package org.apache.tapestry5.ioc
+
+
+class PerThreadScopeSpec extends AbstractRegistrySpecification {
+
+ def "ensure that different threads see different implementations"() {
+ def threadExecuted = false
+
+ buildRegistry PerThreadModule
+
+ def holder = getService StringHolder
+
+ when:
+
+ holder.value = "fred"
+
+ then:
+
+ holder.value == "fred"
+
+ when:
+
+ Thread t = new Thread({
+ assert holder.value == null
+
+ holder.value = "barney"
+
+ assert holder.value == "barney"
+
+ threadExecuted = true
+
+ cleanupThread()
+ })
+
+ t.start()
+ t.join()
+
+ then:
+
+ threadExecuted
+ holder.value == "fred"
+ }
+
+ def "services with out a service interface must use the default scope"() {
+
+ buildRegistry ScopeMismatchModule
+
+ when:
+
+ getService StringBuilder
+
+ then:
+
+ Exception e = thrown()
+
+ e.message.contains "Error building service proxy for service 'ScopeRequiresAProxyAndNoInterfaceIsProvided'"
+ e.message.contains "Service scope 'perthread' requires a proxy"
+ }
+
+ def "ensure that perthread services are discarded by cleanupThread()"() {
+ buildRegistry PerThreadModule
+
+ when:
+
+ def holder = getService StringHolder
+
+ then:
+
+ holder.value == null
+
+ when:
+
+ holder.value = "fred"
+
+ then:
+
+ holder.value == "fred"
+
+ when:
+
+ cleanupThread()
+
+ then:
+
+ holder.value == null
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cf890643/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/RegistryBuilderSpec.groovy
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/RegistryBuilderSpec.groovy b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/RegistryBuilderSpec.groovy
index 5fb91b7..98db472 100644
--- a/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/RegistryBuilderSpec.groovy
+++ b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/RegistryBuilderSpec.groovy
@@ -11,9 +11,6 @@ class RegistryBuilderSpec extends Specification {
def "@SubModule annotation is honored"() {
when:
- // Borrowed from IntegrationTest, this will only work if both FredModule and BarneyModule
- // are loaded.
-
Registry r = new RegistryBuilder().add(MasterModule).build()
def service = r.getService("UnorderedNames", NameListHolder)
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cf890643/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/RegistryConstructionAndRuntimeErrorsSpec.groovy
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/RegistryConstructionAndRuntimeErrorsSpec.groovy b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/RegistryConstructionAndRuntimeErrorsSpec.groovy
new file mode 100644
index 0000000..70da305
--- /dev/null
+++ b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/RegistryConstructionAndRuntimeErrorsSpec.groovy
@@ -0,0 +1,117 @@
+package org.apache.tapestry5.ioc
+
+import org.apache.tapestry5.ioc.internal.ExtraPublicConstructorsModule
+import org.apache.tapestry5.ioc.internal.PrivateConstructorModule
+import org.apache.tapestry5.ioc.internal.UpcaseService
+
+/**
+ * A few tests that are easiest (or even just possible) by building a Registry and trying out a few
+ * things.
+ */
+class RegistryConstructionAndRuntimeErrorsSpec extends AbstractRegistrySpecification {
+
+ def "duplicate service names are a failure"() {
+ when:
+
+ buildRegistry FredModule, DuplicateFredModule
+
+ then:
+
+ RuntimeException ex = thrown()
+
+ ex.message.startsWith "Service id 'Fred' has already been defined by"
+
+ // Can't check entire message, can't guarantee what order modules will be processed in
+ }
+
+ def "service with unknown scope fails at service proxy creation"() {
+ buildRegistry UnknownScopeModule
+
+ when:
+
+ getService "UnknownScope", Runnable
+
+ then:
+
+ Exception e = thrown()
+
+ e.message.contains "Error building service proxy for service 'UnknownScope'"
+ e.message.contains "Unknown service scope 'magic'"
+ }
+
+ def "ensure that recursive module construction is detected"() {
+
+ buildRegistry RecursiveConstructorModule
+
+ def runnable = getService "Runnable", Runnable
+
+ when:
+
+ // We can get the proxy, but invoking a method causes
+ // the module to be instantiated ... but that also invokes a method on
+ // the proxy.
+
+ runnable.run()
+
+ then:
+
+ RuntimeException e = thrown()
+
+ e.message.contains "has failed due to recursion"
+ }
+
+ def "a module class must have a public constructor"() {
+
+ buildRegistry PrivateConstructorModule
+
+ def trigger = getService "Trigger", Runnable
+
+ when:
+
+ trigger.run()
+
+ then:
+
+ RuntimeException e = thrown()
+
+ e.message.contains "Module class org.apache.tapestry5.ioc.internal.PrivateConstructorModule does not contain any public constructors."
+ }
+
+ def "extra public constructors on a module class are ignored"() {
+
+ buildRegistry ExtraPublicConstructorsModule
+
+ when: "forcing the module to be instantiated"
+
+ def upcase = getService UpcaseService
+
+ then: "no exception when instantiating the module"
+
+ upcase.upcase('Hello, ${fred}') == "HELLO, FLINTSTONE"
+ }
+
+ def "extra public methods on module classes are exceptions"() {
+ when:
+ buildRegistry ExtraMethodsModule
+
+ then:
+
+ RuntimeException e = thrown()
+
+ e.message.contains "Module class org.apache.tapestry5.ioc.ExtraMethodsModule contains unrecognized public methods: "
+ e.message.contains "thisMethodIsInvalid()"
+ e.message.contains "soIsThisMethod()"
+ }
+
+ def "can not use withSimpleId() when binding a service interface to a ServiceBuilder callback"() {
+ when:
+
+ buildRegistry NoImplementationClassForSimpleIdModule
+
+ then:
+
+ RuntimeException e = thrown()
+
+ e.message.contains "No defined implementation class to generate simple id from"
+ }
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cf890643/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/RegistrySpec.groovy
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/RegistrySpec.groovy b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/RegistrySpec.groovy
new file mode 100644
index 0000000..d8432cc
--- /dev/null
+++ b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/RegistrySpec.groovy
@@ -0,0 +1,53 @@
+package org.apache.tapestry5.ioc
+
+import org.apache.tapestry5.ioc.internal.services.StartupModule2
+
+class RegistrySpec extends AbstractRegistrySpecification {
+
+ def "symbol in Registry.getService() is expanded"() {
+
+ buildRegistry GreeterModule
+
+ when:
+
+ def greeter = getService '${greeter}', Greeter
+
+ then:
+
+ greeter.greeting == "Hello"
+ greeter.toString() == "<Proxy for HelloGreeter(org.apache.tapestry5.ioc.Greeter)>"
+ }
+
+ def "circular module references are ignored"() {
+ buildRegistry HelterModule
+
+ when:
+
+ def helter = getService "Helter", Runnable
+ def skelter = getService "Skelter", Runnable
+
+ then:
+
+ !helter.is(skelter)
+ }
+
+ def "@Startup annotation support"() {
+ when:
+
+ buildRegistry StartupModule2
+
+ then:
+
+ !StartupModule2.staticStartupInvoked
+ !StartupModule2.instanceStartupInvoked
+
+ when:
+
+ performRegistryStartup()
+
+ then:
+
+ StartupModule2.staticStartupInvoked
+ StartupModule2.instanceStartupInvoked
+ }
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cf890643/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/ServiceActivityScoreboardSpec.groovy
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/ServiceActivityScoreboardSpec.groovy b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/ServiceActivityScoreboardSpec.groovy
new file mode 100644
index 0000000..98a4914
--- /dev/null
+++ b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/ServiceActivityScoreboardSpec.groovy
@@ -0,0 +1,74 @@
+package org.apache.tapestry5.ioc
+
+import org.apache.tapestry5.ioc.services.ServiceActivityScoreboard
+import org.apache.tapestry5.ioc.services.Status
+import org.apache.tapestry5.ioc.services.TypeCoercer
+
+class ServiceActivityScoreboardSpec extends AbstractRegistrySpecification {
+
+ def "general cursory test"() {
+ buildRegistry GreeterModule
+
+ def scoreboard = getService ServiceActivityScoreboard
+
+ when:
+
+ def tc = getService TypeCoercer
+
+ tc.coerce "123", Integer
+
+ getService "BlueGreeter", Greeter
+
+ then:
+
+ def activity = scoreboard.serviceActivity
+
+ !activity.empty
+
+ activity.find({ it.serviceId == "TypeCoercer" }).status == Status.REAL
+
+ def ppf = activity.find { it.serviceId == "PlasticProxyFactory" }
+ ppf.status == Status.BUILTIN
+
+
+ def rg = activity.find { it.serviceId == "RedGreeter1" }
+ rg.status == Status.DEFINED
+ rg.markers.contains RedMarker
+ !rg.markers.contains(BlueMarker)
+
+ def bg = activity.find { it.serviceId == "BlueGreeter"}
+
+ bg.status == Status.VIRTUAL
+ bg.markers.contains BlueMarker
+ !bg.markers.contains(RedMarker)
+ }
+
+ def "scoreboard entry for perthread services is itself perthread"() {
+
+ buildRegistry GreeterModule, PerThreadModule
+
+ def scoreboard = getService ServiceActivityScoreboard
+
+ def holder = getService StringHolder
+
+ when:
+
+ Thread t = new Thread({
+ holder.value = "barney"
+ assert holder.value == "barney"
+
+ assert scoreboard.serviceActivity.find({ it.serviceId == "StringHolder"}).status == Status.REAL
+
+ cleanupThread()
+ })
+
+ t.start()
+ t.join()
+
+ then:
+
+ scoreboard.serviceActivity.find({ it.serviceId == "StringHolder"}).status == Status.VIRTUAL
+
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cf890643/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/ServiceBinderSpec.groovy
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/ServiceBinderSpec.groovy b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/ServiceBinderSpec.groovy
new file mode 100644
index 0000000..30448fc
--- /dev/null
+++ b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/ServiceBinderSpec.groovy
@@ -0,0 +1,35 @@
+package org.apache.tapestry5.ioc
+
+
+class ServiceBinderSpec extends AbstractRegistrySpecification {
+
+ def "a service implementation may be created via a ServiceBuilder callback"() {
+ buildRegistry ServiceBuilderModule
+
+ when:
+
+ def g = getService "Greeter", Greeter
+
+ then:
+ g.greeting == "Greetings from service Greeter."
+ }
+
+ def "verify exception reporting for ServiceBuilder that throws an exception"() {
+
+ buildRegistry ServiceBuilderModule
+
+ def g = getService "BrokenGreeter", Greeter
+
+ when:
+
+ g.greeting
+
+ then:
+
+ Exception e = thrown()
+
+ e.message.contains "Exception constructing service 'BrokenGreeter'"
+ e.message.contains "Failure inside ServiceBuilder callback."
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cf890643/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/ServiceLookupSpec.groovy
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/ServiceLookupSpec.groovy b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/ServiceLookupSpec.groovy
new file mode 100644
index 0000000..5a9828a
--- /dev/null
+++ b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/ServiceLookupSpec.groovy
@@ -0,0 +1,116 @@
+package org.apache.tapestry5.ioc
+
+import org.apache.tapestry5.ioc.services.Builtin
+import org.apache.tapestry5.ioc.services.TypeCoercer
+
+import java.sql.PreparedStatement
+
+class ServiceLookupSpec extends AbstractRegistrySpecification {
+
+ def "access to services by id is case insensitive"() {
+
+ buildRegistry FredModule
+
+ when:
+
+ def r1 = getService "Fred", Runnable
+ def r2 = getService "FRED", Runnable
+
+ then:
+
+ r1.is r2
+
+ }
+
+ def "verify exception when accessing service by unknown id"() {
+
+ buildRegistry()
+
+ when:
+
+ getService "PeekABoo", Runnable
+
+ then:
+
+ RuntimeException e = thrown()
+
+ e.message.contains "Service id 'PeekABoo' is not defined by any module."
+ }
+
+ def "verify exception when accessing a service by type and there are no matching services"() {
+
+ buildRegistry()
+
+ when:
+
+ getService PreparedStatement
+
+ then:
+
+ RuntimeException e = thrown()
+
+ e.message == "No service implements the interface java.sql.PreparedStatement."
+ }
+
+ def "verify exception when accessing a service by type and there are multiple matches"() {
+ buildRegistry DuplicateServiceTypeModule
+
+ when:
+
+ getService Pingable
+
+ then:
+
+ RuntimeException e = thrown()
+
+ e.message == "Service interface org.apache.tapestry5.ioc.Pingable is matched by 2 services: Barney, Fred. Automatic dependency resolution requires that exactly one service implement the interface."
+ }
+
+ def "access to builtin service via marker annotation"() {
+ Builtin annotation = Mock()
+ AnnotationProvider ap = Mock()
+
+ buildRegistry()
+
+ def tc1 = getService "TypeCoercer", TypeCoercer
+
+ when:
+
+ def tc2 = getObject TypeCoercer, ap
+
+ then:
+
+ 1 * ap.getAnnotation(Builtin) >> annotation
+
+ tc2.is tc1
+ }
+
+ def "lookup service by type and markers"() {
+ buildRegistry GreeterModule
+
+ when:
+
+ def blue = getService Greeter, BlueMarker
+
+ then:
+
+ blue.greeting == "Blue"
+ }
+
+ def "use of the @Local annotation disambiguates from multiple services"() {
+ buildRegistry GreeterModule, LocalModule
+
+
+ when:
+
+ // The implementation of this class relies on a @Local injection to find
+ // a specific Greeter implementation
+
+ StringHolder holder = getService "LocalGreeterHolder", StringHolder
+
+ then:
+
+ holder.value == "Hello, y'all!"
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cf890643/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/ServiceProxySpec.groovy
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/ServiceProxySpec.groovy b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/ServiceProxySpec.groovy
new file mode 100644
index 0000000..9222792
--- /dev/null
+++ b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/ServiceProxySpec.groovy
@@ -0,0 +1,96 @@
+package org.apache.tapestry5.ioc
+
+class ServiceProxySpec extends AbstractRegistrySpecification {
+
+ def "shutdown deactivaties proxies"() {
+ buildRegistry FredModule, BarneyModule
+
+ def fred = getService "Fred", Runnable
+
+ fred.run()
+
+ shutdown()
+
+ when:
+
+ fred.run()
+
+ then:
+
+ RuntimeException ex = thrown()
+
+ ex.message.contains "Proxy for service Fred is no longer active because the IOC Registry has been shut down."
+
+ fred.toString() == "<Proxy for Fred(java.lang.Runnable)>"
+
+ cleanup:
+
+ registry = null
+ }
+
+ def "show that services defined without a implementation are instantiated immediately"() {
+ buildRegistry NonProxiedServiceModule
+
+ when:
+
+ def holder = getService StringHolder
+
+ then:
+
+ holder instanceof StringHolderImpl // and not some proxy
+ }
+
+ def "service builder methods with a class (not interface) return type are not proxied, but are cached"() {
+
+ buildRegistry ConcreteServiceBuilderModule
+
+ when:
+
+ def h1 = getService StringHolder
+
+ then: "not proxied"
+
+ h1 instanceof StringHolderImpl
+
+ when:
+
+ def h2 = getService StringHolder
+
+ then: "cached"
+
+ h2.is h1
+ }
+
+ def "verify that a proxy for an autobuilt object lazily instantiates the implementation"() {
+
+ buildRegistry()
+
+ expect:
+ IntegrationTestFixture.countingGreeterInstantiationCount == 0
+
+ when: "obtaining the proxy"
+
+ def g = proxy Greeter, CountingGreeterImpl
+
+ then: "the implementation is not yet instantiated"
+
+ IntegrationTestFixture.countingGreeterInstantiationCount == 0
+
+ when: "invoking toString() on the proxy"
+
+ assert g.toString() == "<Autoreload proxy org.apache.tapestry5.ioc.CountingGreeterImpl(org.apache.tapestry5.ioc.Greeter)>"
+
+ then: "the implementation is not yet instantiated"
+
+ IntegrationTestFixture.countingGreeterInstantiationCount == 0
+
+ when: "invoking other methods on the proxy"
+
+ assert g.greeting == "Hello"
+
+ then: "the implementation is now instantiated"
+
+ IntegrationTestFixture.countingGreeterInstantiationCount == 1
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cf890643/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/BarneyModule.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/BarneyModule.java b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/BarneyModule.java
index 7969317..eeb143b 100644
--- a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/BarneyModule.java
+++ b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/BarneyModule.java
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 2007, 2012 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -14,12 +14,12 @@
package org.apache.tapestry5.ioc;
+import org.apache.tapestry5.ioc.annotations.Contribute;
import org.apache.tapestry5.ioc.annotations.Match;
import org.apache.tapestry5.ioc.annotations.Order;
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry5.ioc.services.StrategyBuilder;
-import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -27,94 +27,88 @@ import java.util.Map;
* Module used to demonstrate decorator ordering.
*/
-public class BarneyModule
-{
- @Match(
- {"UnorderedNames", "Fred", "PrivateFredAlias"})
- @Order("after:Beta")
- public Object decorateGamma(Object delegate, DecoratorList list)
- {
- list.add("gamma");
-
- return null;
- }
-
- public Sizer buildSizer(final Map<Class, Sizer> configuration)
- {
- return new Sizer()
- {
- public int size(Object object)
- {
- if (object == null) return 0;
-
- Sizer sizer = configuration.get(object.getClass());
-
- if (sizer != null) return sizer.size(object);
-
- return 1;
- }
- };
- }
-
- public void contributeSizer(MappedConfiguration<Class, Sizer> configuration)
- {
- Sizer listSizer = new Sizer()
- {
- public int size(Object object)
- {
- List list = (List) object;
-
- return list.size();
- }
- };
-
- Sizer mapSizer = new Sizer()
- {
- public int size(Object object)
- {
- Map map = (Map) object;
-
- return map.size();
- }
- };
-
- // Have to work on concrete class, rather than type, until we move the StrategyFactory
- // over from HiveMind.
-
- configuration.add(ArrayList.class, listSizer);
- configuration.add(HashMap.class, mapSizer);
- }
-
- /**
- * Put DecoratorList in module barney, where so it won't accidentally be decorated (which recusively builds the
- * service, and is caught as a failure).
- */
- public DecoratorList buildDecoratorList()
- {
- return new DecoratorList()
- {
- private List<String> names = CollectionFactory.newList();
-
- public void add(String name)
- {
- names.add(name);
- }
-
- public List<String> getNames()
- {
- return names;
- }
- };
- }
-
- public void contributeUnorderedNames(Configuration<String> configuration)
- {
- configuration.add("Gamma");
- }
-
- public void contributeStringLookup(MappedConfiguration<String, String> configuration)
- {
- configuration.add("barney", "BARNEY");
- configuration.add("betty", "BETTY");
- }
+public class BarneyModule {
+ @Match(
+ {"UnorderedNames", "Fred", "PrivateFredAlias"})
+ @Order("after:Beta")
+ public Object decorateGamma(Object delegate, DecoratorList list) {
+ list.add("gamma");
+
+ return null;
+ }
+
+ public Sizer buildSizer(final Map<Class, Sizer> configuration, StrategyBuilder builder) {
+
+ return builder.build(Sizer.class, configuration);
+ }
+
+ public void contributeSizer(MappedConfiguration<Class, Sizer> configuration) {
+ Sizer listSizer = new Sizer() {
+ public int size(Object object) {
+ List list = (List) object;
+
+ return list.size();
+ }
+ };
+
+ Sizer mapSizer = new Sizer() {
+ public int size(Object object) {
+ Map map = (Map) object;
+
+ return map.size();
+ }
+ };
+
+
+ configuration.add(List.class, listSizer);
+ configuration.add(Map.class, mapSizer);
+ }
+
+ @Contribute(Sizer.class)
+ public void moreSizerContributions(MappedConfiguration<Class, Sizer> configuration) {
+ Sizer defaultSizer = new Sizer() {
+ @Override
+ public int size(Object object) {
+ return 1;
+ }
+ };
+
+ Sizer nullSizer = new Sizer() {
+ @Override
+ public int size(Object object) {
+ return 0;
+ }
+ };
+
+ configuration.add(Object.class, defaultSizer);
+ configuration.add(void.class, nullSizer);
+
+ }
+
+ /**
+ * Put DecoratorList in module barney, where so it won't accidentally be decorated (which recusively builds the
+ * service, and is caught as a failure).
+ */
+ public DecoratorList buildDecoratorList() {
+ return new DecoratorList() {
+ private List<String> names = CollectionFactory.newList();
+
+ public void add(String name) {
+ names.add(name);
+ }
+
+ public List<String> getNames() {
+ return names;
+ }
+ };
+ }
+
+ public void contributeUnorderedNames(Configuration<String> configuration) {
+ configuration.add("Gamma");
+ }
+
+ public void contributeStringLookup(MappedConfiguration<String, String> configuration) {
+ configuration.add("barney", "BARNEY");
+ configuration.add("betty", "BETTY");
+ }
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/cf890643/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/CountingGreeterImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/CountingGreeterImpl.java b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/CountingGreeterImpl.java
index a647560..1df3097 100644
--- a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/CountingGreeterImpl.java
+++ b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/CountingGreeterImpl.java
@@ -1,4 +1,4 @@
-// Copyright 2007, 2010 The Apache Software Foundation
+// Copyright 2007, 2010, 2012 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@ public class CountingGreeterImpl implements Greeter
{
public CountingGreeterImpl()
{
- IntegrationTest.countingGreeterInstantiationCount++;
+ IntegrationTestFixture.countingGreeterInstantiationCount++;
}
public String getGreeting()