001: package org.nanocontainer.script.groovy;
002:
003: import java.io.IOException;
004: import java.io.Reader;
005: import java.io.StringReader;
006: import java.io.StringWriter;
007: import java.util.ArrayList;
008: import java.util.Vector;
009:
010: import org.jmock.Mock;
011: import org.nanocontainer.NanoPicoContainer;
012: import org.nanocontainer.TestHelper;
013: import org.nanocontainer.integrationkit.PicoCompositionException;
014: import org.nanocontainer.reflection.DefaultNanoPicoContainer;
015: import org.nanocontainer.script.AbstractScriptedContainerBuilderTestCase;
016: import org.nanocontainer.script.BarDecoratingPicoContainer;
017: import org.nanocontainer.script.FooDecoratingPicoContainer;
018: import org.nanocontainer.script.NanoContainerMarkupException;
019: import org.nanocontainer.testmodel.A;
020: import org.nanocontainer.testmodel.B;
021: import org.nanocontainer.testmodel.HasParams;
022: import org.nanocontainer.testmodel.ParentAssemblyScope;
023: import org.nanocontainer.testmodel.SomeAssemblyScope;
024: import org.nanocontainer.testmodel.WebServerConfig;
025: import org.nanocontainer.testmodel.X;
026: import org.picocontainer.ComponentAdapter;
027: import org.picocontainer.MutablePicoContainer;
028: import org.picocontainer.PicoContainer;
029: import org.picocontainer.defaults.ComponentAdapterFactory;
030: import org.picocontainer.defaults.InstanceComponentAdapter;
031: import org.picocontainer.defaults.SetterInjectionComponentAdapter;
032: import org.picocontainer.defaults.SetterInjectionComponentAdapterFactory;
033: import org.picocontainer.defaults.UnsatisfiableDependenciesException;
034: import java.io.File;
035: import java.net.URLClassLoader;
036: import java.net.URL;
037:
038: /**
039: *
040: * @author Paul Hammant
041: * @author Mauro Talevi
042: * @version $Revision: 1775 $
043: */
044: public class GroovyNodeBuilderTestCase extends
045: AbstractScriptedContainerBuilderTestCase {
046: private static final String ASSEMBLY_SCOPE = "SOME_SCOPE";
047:
048: public void testInstantiateBasicScriptable()
049: throws PicoCompositionException {
050: Reader script = new StringReader(
051: ""
052: + "import org.nanocontainer.testmodel.*\n"
053: + "X.reset()\n"
054: + "builder = new org.nanocontainer.script.groovy.GroovyNodeBuilder()\n"
055: + "nano = builder.container {\n"
056: + " component(A)\n" + "}");
057:
058: PicoContainer pico = buildContainer(script, null,
059: ASSEMBLY_SCOPE);
060: // LifecyleContainerBuilder starts the container
061: pico.dispose();
062:
063: assertEquals("Should match the expression", "<A!A",
064: X.componentRecorder);
065: }
066:
067: public void testComponentInstances()
068: throws PicoCompositionException {
069: Reader script = new StringReader(
070: ""
071: + "import org.nanocontainer.testmodel.*\n"
072: + "builder = new org.nanocontainer.script.groovy.GroovyNodeBuilder()\n"
073: + "nano = builder.container {\n"
074: + " component(key:'a', instance:'apple')\n"
075: + " component(key:'b', instance:'banana')\n"
076: + " component(instance:'noKeySpecified')\n"
077: + "}");
078:
079: PicoContainer pico = buildContainer(script, null,
080: ASSEMBLY_SCOPE);
081: assertEquals("apple", pico.getComponentInstance("a"));
082: assertEquals("banana", pico.getComponentInstance("b"));
083: assertEquals("noKeySpecified", pico
084: .getComponentInstance(String.class));
085: }
086:
087: public void testShouldFailWhenNeitherClassNorInstanceIsSpecifiedForComponent() {
088: Reader script = new StringReader(
089: ""
090: + "builder = new org.nanocontainer.script.groovy.GroovyNodeBuilder()\n"
091: + "nano = builder.container {\n"
092: + " component(key:'a')\n" + "}");
093:
094: try {
095: buildContainer(script, null, ASSEMBLY_SCOPE);
096: fail("NanoContainerMarkupException should have been raised");
097: } catch (NanoContainerMarkupException e) {
098: // expected
099: }
100: }
101:
102: public void testShouldAcceptConstantParametersForComponent()
103: throws PicoCompositionException {
104: Reader script = new StringReader(
105: ""
106: + "import org.picocontainer.defaults.ConstantParameter\n"
107: + "import org.nanocontainer.testmodel.*\n"
108: + ""
109: + "builder = new org.nanocontainer.script.groovy.GroovyNodeBuilder()\n"
110: + "nano = builder.container {\n"
111: + " component(key:'byClass', class:HasParams, parameters:[ 'a', 'b', new ConstantParameter('c') ])\n"
112: + " component(key:'byClassString', class:'org.nanocontainer.testmodel.HasParams', parameters:[ 'c', 'a', 't' ])\n"
113: + "}");
114:
115: PicoContainer pico = buildContainer(script, null,
116: ASSEMBLY_SCOPE);
117: HasParams byClass = (HasParams) pico
118: .getComponentInstance("byClass");
119: assertEquals("abc", byClass.getParams());
120:
121: HasParams byClassString = (HasParams) pico
122: .getComponentInstance("byClassString");
123: assertEquals("cat", byClassString.getParams());
124: }
125:
126: public void testShouldAcceptComponentParametersForComponent()
127: throws PicoCompositionException {
128: Reader script = new StringReader(
129: ""
130: + "import org.picocontainer.defaults.ComponentParameter\n"
131: + "import org.nanocontainer.testmodel.*\n"
132: + ""
133: + "builder = new org.nanocontainer.script.groovy.GroovyNodeBuilder()\n"
134: + "nano = builder.container {\n"
135: + " component(key:'a1', class:A)\n"
136: + " component(key:'a2', class:A)\n"
137: + " component(key:'b1', class:B, parameters:[ new ComponentParameter('a1') ])\n"
138: + " component(key:'b2', class:B, parameters:[ new ComponentParameter('a2') ])\n"
139: + "}");
140:
141: PicoContainer pico = buildContainer(script, null,
142: ASSEMBLY_SCOPE);
143: A a1 = (A) pico.getComponentInstance("a1");
144: A a2 = (A) pico.getComponentInstance("a2");
145: B b1 = (B) pico.getComponentInstance("b1");
146: B b2 = (B) pico.getComponentInstance("b2");
147:
148: assertNotNull(a1);
149: assertNotNull(a2);
150: assertNotNull(b1);
151: assertNotNull(b2);
152:
153: assertSame(a1, b1.a);
154: assertSame(a2, b2.a);
155: assertNotSame(a1, a2);
156: assertNotSame(b1, b2);
157: }
158:
159: public void testShouldAcceptComponentParameterWithClassNameKey()
160: throws PicoCompositionException {
161: Reader script = new StringReader(
162: ""
163: + "import org.picocontainer.defaults.ComponentParameter\n"
164: + "import org.nanocontainer.testmodel.*\n"
165: + ""
166: + "builder = new org.nanocontainer.script.groovy.GroovyNodeBuilder()\n"
167: + "nano = builder.container {\n"
168: + " component(class:A)\n"
169: + " component(key:B, class:B, parameters:[ new ComponentParameter(A) ])\n"
170: + "}");
171:
172: PicoContainer pico = buildContainer(script, null,
173: ASSEMBLY_SCOPE);
174: A a = (A) pico.getComponentInstance(A.class);
175: B b = (B) pico.getComponentInstance(B.class);
176:
177: assertNotNull(a);
178: assertNotNull(b);
179: assertSame(a, b.a);
180: }
181:
182: public void testComponentParametersScript() {
183: Reader script = new StringReader(
184: ""
185: + "package org.nanocontainer.script.groovy\n"
186: + "import org.picocontainer.defaults.ComponentParameter\n"
187: + "import org.nanocontainer.testmodel.*\n"
188: + "builder = new GroovyNodeBuilder()\n"
189: + "nano = builder.container {\n"
190: + " component(key:'a', class:A)\n"
191: + " component(key:'b', class:B, parameters:[ new ComponentParameter('a') ])\n"
192: + "}");
193:
194: PicoContainer pico = buildContainer(script, null,
195: ASSEMBLY_SCOPE);
196: A a = (A) pico.getComponentInstance("a");
197: B b = (B) pico.getComponentInstance("b");
198: assertSame(a, b.a);
199: }
200:
201: public void testShouldBeAbleToHandOffToNestedBuilder() {
202: Reader script = new StringReader(
203: ""
204: + "package org.nanocontainer.script.groovy\n"
205: + "import org.nanocontainer.testmodel.*\n"
206: + "builder = new GroovyNodeBuilder()\n"
207: + "builder.registerBuilder(name:'foo', class:'org.nanocontainer.script.groovy.TestingChildBuilder')\n"
208: + "nano = builder.container {\n"
209: + " component(key:'a', class:A)\n"
210: + " foo {\n"
211: + " elephant(key:'b', class:B)\n"
212: + " }\n" + "}");
213:
214: PicoContainer pico = buildContainer(script, null,
215: ASSEMBLY_SCOPE);
216: Object a = pico.getComponentInstance("a");
217: Object b = pico.getComponentInstance("b");
218:
219: assertNotNull(a);
220: assertNotNull(b);
221: }
222:
223: public void testShouldBeAbleToHandOffToNestedBuilderTheInlinedWay() {
224: Reader script = new StringReader(
225: ""
226: + "package org.nanocontainer.script.groovy\n"
227: + "import org.nanocontainer.testmodel.*\n"
228: + "builder = new GroovyNodeBuilder()\n"
229: + "nano = builder.container {\n"
230: + " component(key:'a', class:A)\n"
231: + " newBuilder(class:'org.nanocontainer.script.groovy.TestingChildBuilder') {\n"
232: + " elephant(key:'b', class:B)\n"
233: + " }\n" + "}");
234:
235: PicoContainer pico = buildContainer(script, null,
236: ASSEMBLY_SCOPE);
237: Object a = pico.getComponentInstance("a");
238: Object b = pico.getComponentInstance("b");
239:
240: assertNotNull(a);
241: assertNotNull(b);
242: }
243:
244: public void testInstantiateBasicComponentInDeeperTree() {
245: X.reset();
246: Reader script = new StringReader(""
247: + "package org.nanocontainer.script.groovy\n"
248: + "import org.nanocontainer.testmodel.*\n"
249: + "builder = new GroovyNodeBuilder()\n"
250: + "nano = builder.container {\n"
251: + " container() {\n" + " component(A)\n"
252: + " }\n" + "}");
253:
254: PicoContainer pico = buildContainer(script, null,
255: ASSEMBLY_SCOPE);
256: pico.dispose();
257: assertEquals("Should match the expression", "<A!A",
258: X.componentRecorder);
259: }
260:
261: public void testCustomComponentAdapterFactoryCanBeSpecified() {
262: Reader script = new StringReader(
263: ""
264: + "package org.nanocontainer.script.groovy\n"
265: + "import org.nanocontainer.testmodel.*\n"
266: + "builder = new GroovyNodeBuilder()\n"
267: + "nano = builder.container(componentAdapterFactory:assemblyScope) {\n"
268: + " component(A)\n" + "}");
269:
270: A a = new A();
271: Mock cafMock = mock(ComponentAdapterFactory.class);
272: cafMock.expects(once()).method("createComponentAdapter").with(
273: same(A.class), same(A.class), eq(null)).will(
274: returnValue(new InstanceComponentAdapter(A.class, a)));
275: ComponentAdapterFactory componentAdapterFactory = (ComponentAdapterFactory) cafMock
276: .proxy();
277: PicoContainer pico = buildContainer(script, null,
278: componentAdapterFactory);
279: assertSame(a, pico.getComponentInstanceOfType(A.class));
280: }
281:
282: public void testCustomComponentMonitorCanBeSpecified() {
283: Reader script = new StringReader(
284: ""
285: + "package org.nanocontainer.script.groovy\n"
286: + "import java.io.StringWriter\n"
287: + "import org.picocontainer.monitors.WriterComponentMonitor\n"
288: + "import org.nanocontainer.testmodel.*\n"
289: + "builder = new GroovyNodeBuilder()\n"
290: + "writer = new StringWriter()\n"
291: + "monitor = new WriterComponentMonitor(writer) \n"
292: + "nano = builder.container(componentMonitor: monitor) {\n"
293: + " component(A)\n"
294: + " component(key:StringWriter, instance:writer)\n"
295: + "}");
296:
297: PicoContainer pico = buildContainer(script, null,
298: ASSEMBLY_SCOPE);
299: pico.getComponentInstanceOfType(WebServerConfig.class);
300: StringWriter writer = (StringWriter) pico
301: .getComponentInstanceOfType(StringWriter.class);
302: assertTrue(writer.toString().length() > 0);
303: }
304:
305: public void testCustomComponentMonitorCanBeSpecifiedWhenCAFIsSpecified() {
306: Reader script = new StringReader(
307: ""
308: + "package org.nanocontainer.script.groovy\n"
309: + "import java.io.StringWriter\n"
310: + "import org.picocontainer.defaults.DefaultComponentAdapterFactory\n"
311: + "import org.picocontainer.monitors.WriterComponentMonitor\n"
312: + "import org.nanocontainer.testmodel.*\n"
313: + "builder = new GroovyNodeBuilder()\n"
314: + "writer = new StringWriter()\n"
315: + "monitor = new WriterComponentMonitor(writer) \n"
316: + "nano = builder.container(componentAdapterFactory: new DefaultComponentAdapterFactory(), componentMonitor: monitor) {\n"
317: + " component(A)\n"
318: + " component(key:StringWriter, instance:writer)\n"
319: + "}");
320:
321: PicoContainer pico = buildContainer(script, null,
322: ASSEMBLY_SCOPE);
323: pico.getComponentInstanceOfType(WebServerConfig.class);
324: StringWriter writer = (StringWriter) pico
325: .getComponentInstanceOfType(StringWriter.class);
326: assertTrue(writer.toString().length() > 0);
327: }
328:
329: public void testCustomComponentMonitorCanBeSpecifiedWhenParentIsSpecified() {
330: DefaultNanoPicoContainer parent = new DefaultNanoPicoContainer();
331: Reader script = new StringReader(
332: ""
333: + "package org.nanocontainer.script.groovy\n"
334: + "import java.io.StringWriter\n"
335: + "import org.picocontainer.monitors.WriterComponentMonitor\n"
336: + "import org.nanocontainer.testmodel.*\n"
337: + "builder = new GroovyNodeBuilder()\n"
338: + "writer = new StringWriter()\n"
339: + "monitor = new WriterComponentMonitor(writer) \n"
340: + "nano = builder.container(parent:parent, componentMonitor: monitor) {\n"
341: + " component(A)\n"
342: + " component(key:StringWriter, instance:writer)\n"
343: + "}");
344:
345: PicoContainer pico = buildContainer(script, parent,
346: ASSEMBLY_SCOPE);
347: pico.getComponentInstanceOfType(WebServerConfig.class);
348: StringWriter writer = (StringWriter) pico
349: .getComponentInstanceOfType(StringWriter.class);
350: assertTrue(writer.toString().length() > 0);
351: }
352:
353: public void testCustomComponentMonitorCanBeSpecifiedWhenParentAndCAFAreSpecified() {
354: DefaultNanoPicoContainer parent = new DefaultNanoPicoContainer();
355: Reader script = new StringReader(
356: ""
357: + "package org.nanocontainer.script.groovy\n"
358: + "import java.io.StringWriter\n"
359: + "import org.picocontainer.defaults.DefaultComponentAdapterFactory\n"
360: + "import org.picocontainer.monitors.WriterComponentMonitor\n"
361: + "import org.nanocontainer.testmodel.*\n"
362: + "builder = new GroovyNodeBuilder()\n"
363: + "writer = new StringWriter()\n"
364: + "monitor = new WriterComponentMonitor(writer) \n"
365: + "nano = builder.container(parent:parent, componentAdapterFactory: new DefaultComponentAdapterFactory(), componentMonitor: monitor) {\n"
366: + " component(A)\n"
367: + " component(key:StringWriter, instance:writer)\n"
368: + "}");
369:
370: PicoContainer pico = buildContainer(script, parent,
371: ASSEMBLY_SCOPE);
372: pico.getComponentInstanceOfType(WebServerConfig.class);
373: StringWriter writer = (StringWriter) pico
374: .getComponentInstanceOfType(StringWriter.class);
375: assertTrue(writer.toString().length() > 0);
376: }
377:
378: public void testInstantiateWithImpossibleComponentDependenciesConsideringTheHierarchy() {
379: X.reset();
380: Reader script = new StringReader(""
381: + "package org.nanocontainer.script.groovy\n"
382: + "import org.nanocontainer.testmodel.*\n"
383: + "builder = new GroovyNodeBuilder()\n"
384: + "nano = builder.container {\n" + " component(B)\n"
385: + " container() {\n" + " component(A)\n"
386: + " }\n" + " component(C)\n" + "}");
387:
388: try {
389: buildContainer(script, null, ASSEMBLY_SCOPE);
390: fail("Should not have been able to instansiate component tree due to visibility/parent reasons.");
391: } catch (UnsatisfiableDependenciesException expected) {
392: }
393: }
394:
395: public void testInstantiateWithChildContainerAndStartStopAndDisposeOrderIsCorrect() {
396: X.reset();
397: Reader script = new StringReader(""
398: + "package org.nanocontainer.script.groovy\n"
399: + "import org.nanocontainer.testmodel.*\n"
400: + "builder = new GroovyNodeBuilder()\n"
401: + "nano = builder.container {\n" + " component(A)\n"
402: + " container() {\n" + " component(B)\n"
403: + " }\n" + " component(C)\n" + "}\n");
404:
405: // A and C have no no dependancies. B Depends on A.
406: PicoContainer pico = buildContainer(script, null,
407: ASSEMBLY_SCOPE);
408: //pico.start();
409: pico.stop();
410: pico.dispose();
411:
412: assertEquals("Should match the expression",
413: "<A<C<BB>C>A>!B!C!A", X.componentRecorder);
414: }
415:
416: public void testBuildContainerWithParentAttribute() {
417: DefaultNanoPicoContainer parent = new DefaultNanoPicoContainer();
418: parent.registerComponentInstance("hello", "world");
419:
420: Reader script = new StringReader(""
421: + "package org.nanocontainer.script.groovy\n"
422: + "import org.nanocontainer.testmodel.*\n"
423: + "builder = new GroovyNodeBuilder()\n"
424: + "nano = builder.container(parent:parent) {\n"
425: + " component(A)\n" + "}\n");
426:
427: PicoContainer pico = buildContainer(script, parent,
428: ASSEMBLY_SCOPE);
429: // Should be able to get instance that was registered in the parent container
430: assertEquals("world", pico.getComponentInstance("hello"));
431: }
432:
433: public void testBuildContainerWithParentDependencyAndAssemblyScope() {
434: DefaultNanoPicoContainer parent = new DefaultNanoPicoContainer();
435: parent.registerComponentImplementation("a", A.class);
436:
437: Reader script = new StringReader(
438: ""
439: + "package org.nanocontainer.script.groovy\n"
440: + "import org.nanocontainer.testmodel.*\n"
441: + "builder = new GroovyNodeBuilder()\n"
442: + "nano = builder.container(parent:parent) {\n"
443: + " if ( assemblyScope instanceof SomeAssemblyScope ){\n "
444: + " component(B)\n" + " }\n " + "}\n");
445:
446: PicoContainer pico = buildContainer(script, parent,
447: new SomeAssemblyScope());
448: assertNotNull(pico.getComponentInstanceOfType(B.class));
449: }
450:
451: public void testBuildContainerWithParentAndChildAssemblyScopes()
452: throws IOException {
453: String scriptValue = (""
454: + "package org.nanocontainer.script.groovy\n"
455: + "import org.nanocontainer.testmodel.*\n"
456: + "builder = new GroovyNodeBuilder()\n"
457: + "nano = builder.container(parent:parent) {\n"
458: + " System.out.println('assemblyScope:'+assemblyScope)\n "
459: + " if ( assemblyScope instanceof ParentAssemblyScope ){\n "
460: + " System.out.println('parent scope')\n "
461: + " component(A)\n"
462: + " } else if ( assemblyScope instanceof SomeAssemblyScope ){\n "
463: + " System.out.println('child scope')\n "
464: + " component(B)\n"
465: + " } else { \n"
466: + " throw new IllegalArgumentException('Invalid Scope: ' + assemblyScope.getClass().getName())\n"
467: + " System.out.println('Invalid scope')\n "
468: + " } \n " + "}\n");
469:
470: Reader script = new StringReader(scriptValue);
471: NanoPicoContainer parent = new DefaultNanoPicoContainer(
472: buildContainer(script, null, new ParentAssemblyScope()));
473:
474: assertNotNull(parent.getComponentAdapterOfType(A.class));
475:
476: script = new StringReader(scriptValue);
477: PicoContainer pico = buildContainer(script, parent,
478: new SomeAssemblyScope());
479: assertNotNull(pico.getComponentInstance(B.class));
480: }
481:
482: public void testBuildContainerWhenExpectedParentDependencyIsNotFound() {
483: DefaultNanoPicoContainer parent = new DefaultNanoPicoContainer();
484:
485: Reader script = new StringReader(
486: ""
487: + "package org.nanocontainer.script.groovy\n"
488: + "import org.nanocontainer.testmodel.*\n"
489: + "builder = new GroovyNodeBuilder()\n"
490: + "nano = builder.container(parent:parent) {\n"
491: + " if ( assemblyScope instanceof SomeAssemblyScope ){\n "
492: + " component(B)\n" + " }\n " + "}\n");
493:
494: try {
495: buildContainer(script, parent, new SomeAssemblyScope());
496: fail("UnsatisfiableDependenciesException expected");
497: } catch (UnsatisfiableDependenciesException e) {
498: // expected
499: }
500: }
501:
502: public void testBuildContainerWithParentAttributesPropagatesComponentAdapterFactory() {
503: DefaultNanoPicoContainer parent = new DefaultNanoPicoContainer(
504: new SetterInjectionComponentAdapterFactory());
505: Reader script = new StringReader(""
506: + "package org.nanocontainer.script.groovy\n"
507: + "import org.nanocontainer.testmodel.*\n"
508: + "builder = new GroovyNodeBuilder()\n"
509: + "nano = builder.container(parent:parent) {\n" + "}\n");
510:
511: MutablePicoContainer pico = (MutablePicoContainer) buildContainer(
512: script, parent, ASSEMBLY_SCOPE);
513: // Should be able to get instance that was registered in the parent container
514: ComponentAdapter componentAdapter = pico
515: .registerComponentImplementation(String.class);
516: assertTrue(
517: "ComponentAdapter should be originally defined by parent",
518: componentAdapter instanceof SetterInjectionComponentAdapter);
519: }
520:
521: public void testExceptionThrownWhenParentAttributeDefinedWithinChild() {
522: DefaultNanoPicoContainer parent = new DefaultNanoPicoContainer(
523: new SetterInjectionComponentAdapterFactory());
524: Reader script = new StringReader(""
525: + "package org.nanocontainer.script.groovy\n"
526: + "import org.nanocontainer.testmodel.*\n"
527: + "nano = new GroovyNodeBuilder().container() {\n"
528: + " component(A)\n"
529: + " container(parent:parent) {\n"
530: + " component(B)\n" + " }\n" + "}\n");
531:
532: try {
533: buildContainer(script, parent, ASSEMBLY_SCOPE);
534: fail("NanoContainerMarkupException should have been thrown.");
535: } catch (NanoContainerMarkupException ignore) {
536: // expected
537: }
538: }
539:
540: // TODO
541: public void testSpuriousAttributes() {
542: DefaultNanoPicoContainer parent = new DefaultNanoPicoContainer();
543:
544: Reader script = new StringReader(""
545: + "package org.nanocontainer.script.groovy\n"
546: + "import org.nanocontainer.testmodel.*\n"
547: + "builder = new GroovyNodeBuilder()\n"
548: + "nano = builder.container(jim:'Jam', foo:'bar') {\n" +
549:
550: "}\n");
551: try {
552: buildContainer(script, parent, ASSEMBLY_SCOPE);
553: //fail("Should throw exception upon spurious attributes?");
554: } catch (NanoContainerMarkupException ex) {
555: //ok?
556: }
557: }
558:
559: public void testWithDynamicClassPathThatDoesNotExist() {
560: DefaultNanoPicoContainer parent = new DefaultNanoPicoContainer();
561: try {
562: Reader script = new StringReader(
563: ""
564: + " child = null\n"
565: + " pico = builder.container {\n"
566: + " classPathElement(path:'this/path/does/not/exist.jar')\n"
567: + " component(class:\"FooBar\") "
568: + " }");
569:
570: buildContainer(script, parent, ASSEMBLY_SCOPE);
571: fail("should have barfed with bad path exception");
572: } catch (NanoContainerMarkupException e) {
573: // excpected
574: }
575:
576: }
577:
578: public void testWithDynamicClassPath() {
579: DefaultNanoPicoContainer parent = new DefaultNanoPicoContainer();
580: Reader script = new StringReader(
581: " builder = new org.nanocontainer.script.groovy.GroovyNodeBuilder()\n"
582: + " File testCompJar = org.nanocontainer.TestHelper.getTestCompJarFile()\n"
583: + " compJarPath = testCompJar.getCanonicalPath()\n"
584: + " child = null\n"
585: + " pico = builder.container {\n"
586: + " classPathElement(path:compJarPath)\n"
587: + " component(class:\"TestComp\")\n"
588: + " }");
589:
590: MutablePicoContainer pico = (MutablePicoContainer) buildContainer(
591: script, parent, ASSEMBLY_SCOPE);
592:
593: assertTrue(pico.getComponentInstances().size() == 1);
594: assertEquals("TestComp", pico.getComponentInstances().get(0)
595: .getClass().getName());
596: }
597:
598: public void testWithDynamicClassPathWithPermissions() {
599: DefaultNanoPicoContainer parent = new DefaultNanoPicoContainer();
600: Reader script = new StringReader(
601: ""
602: + " builder = new org.nanocontainer.script.groovy.GroovyNodeBuilder()\n"
603: + " File testCompJar = org.nanocontainer.TestHelper.getTestCompJarFile()\n"
604: + " compJarPath = testCompJar.getCanonicalPath()\n"
605: + " child = null\n"
606: + " pico = builder.container {\n"
607: + " classPathElement(path:compJarPath) {\n"
608: + " grant(new java.net.SocketPermission('google.com','connect'))\n"
609: + " }\n"
610: + " component(class:\"TestComp\")\n"
611: + " }" + "");
612:
613: MutablePicoContainer pico = (MutablePicoContainer) buildContainer(
614: script, parent, ASSEMBLY_SCOPE);
615:
616: assertTrue(pico.getComponentInstances().size() == 1);
617: // can't actually test the permission under JUNIT control. We're just
618: // testing the syntax here.
619: }
620:
621: public void testGrantPermissionInWrongPlace() {
622: DefaultNanoPicoContainer parent = new DefaultNanoPicoContainer();
623: try {
624: Reader script = new StringReader(
625: ""
626: + " builder = new org.nanocontainer.script.groovy.GroovyNodeBuilder()\n"
627: + " File testCompJar = org.nanocontainer.TestHelper.getTestCompJarFile()\n"
628: + " compJarPath = testCompJar.getCanonicalPath()\n"
629: + " child = null\n"
630: + " pico = builder.container {\n"
631: + " grant(new java.net.SocketPermission('google.com','connect'))\n"
632: + " }" + "");
633:
634: buildContainer(script, parent, ASSEMBLY_SCOPE);
635: fail("should barf with [Don't know how to create a 'grant' child] exception");
636: } catch (NanoContainerMarkupException e) {
637: assertTrue(e.getMessage().indexOf(
638: "Don't know how to create a 'grant' child") > -1);
639: }
640:
641: }
642:
643: /**
644: * Santity check to make sure testcomp doesn't exist in the testing classpath
645: * otherwise all the tests that depend on the custom classpaths are suspect.
646: */
647: public void testTestCompIsNotAvailableViaSystemClassPath() {
648: try {
649: Class testComp = getClass().getClassLoader().loadClass(
650: "TestComp");
651: fail("Invalid configuration TestComp exists in system classpath. ");
652: } catch (ClassNotFoundException ex) {
653: //ok.
654: }
655:
656: }
657:
658: public void testWithParentClassPathPropagatesWithNoParentContainer()
659: throws IOException {
660: File testCompJar = TestHelper.getTestCompJarFile();
661:
662: URLClassLoader classLoader = new URLClassLoader(
663: new URL[] { testCompJar.toURL() }, this .getClass()
664: .getClassLoader());
665: Class testComp = null;
666:
667: try {
668: testComp = classLoader.loadClass("TestComp");
669: } catch (ClassNotFoundException ex) {
670: fail("Unable to load test component from the jar using a url classloader");
671: }
672: Reader script = new StringReader(""
673: + "pico = builder.container(parent:parent) {\n"
674: + " component(class:\"TestComp\")\n" + "}");
675:
676: PicoContainer pico = buildContainer(new GroovyContainerBuilder(
677: script, classLoader), null, null);
678: assertNotNull(pico);
679: Object testCompInstance = pico.getComponentInstance(testComp
680: .getName());
681: assertSame(testCompInstance.getClass(), testComp);
682:
683: }
684:
685: public void testValidationTurnedOnThrowsExceptionForUnknownAttributes() {
686: DefaultNanoPicoContainer parent = new DefaultNanoPicoContainer();
687: Reader script = new StringReader(
688: "import org.nanocontainer.script.NullNodeBuilderDecorationDelegate\n"
689: + "import org.nanocontainer.script.groovy.GroovyNodeBuilder\n"
690: + "import org.nanocontainer.testmodel.*\n"
691: + "builder = new GroovyNodeBuilder(new NullNodeBuilderDecorationDelegate(), GroovyNodeBuilder.PERFORM_ATTRIBUTE_VALIDATION)\n"
692: + "nano = builder.container {\n"
693: + " component(key:'a', instance:'apple', badAttribute:'foo')\n"
694: + "}");
695:
696: try {
697: buildContainer(script, parent, ASSEMBLY_SCOPE);
698: fail("GroovyNodeBuilder with validation should have thrown NanoContainerMarkupException");
699: } catch (GroovyCompilationException ex) {
700: //Weed out the groovy compilation exceptions
701: throw ex;
702: } catch (NanoContainerMarkupException ex) {
703: //a-ok
704: }
705: }
706:
707: public void testValidationTurnedOffDoesntThrowExceptionForUnknownAttributes() {
708: DefaultNanoPicoContainer parent = new DefaultNanoPicoContainer();
709: Reader script = new StringReader(
710: "import org.nanocontainer.script.NullNodeBuilderDecorationDelegate\n"
711: + "import org.nanocontainer.script.groovy.GroovyNodeBuilder\n"
712: + "import org.nanocontainer.testmodel.*\n"
713: + "builder = new GroovyNodeBuilder(new NullNodeBuilderDecorationDelegate(), GroovyNodeBuilder.SKIP_ATTRIBUTE_VALIDATION)\n"
714: + "nano = builder.container {\n"
715: + " component(key:'a', instance:'apple', badAttribute:'foo')\n"
716: + "}");
717:
718: try {
719: buildContainer(script, parent, ASSEMBLY_SCOPE);
720: //a-ok
721: } catch (GroovyCompilationException ex) {
722: //Weed out the groovy compilation exceptions
723: throw ex;
724: } catch (NanoContainerMarkupException ex) {
725: fail("GroovyNodeBuilder with validation turned off should never have thrown NanoContainerMarkupException: "
726: + ex.getMessage());
727: }
728:
729: }
730:
731: public void testComponentAdapterIsPotentiallyScriptable()
732: throws PicoCompositionException {
733: Reader script = new StringReader(
734: ""
735: + "import org.nanocontainer.testmodel.*\n"
736: + "X.reset()\n"
737: + "builder = new org.nanocontainer.script.groovy.OldGroovyNodeBuilder()\n"
738: + "nano = builder.container {\n"
739: + " ca = component(java.lang.Object) \n"
740: + " component(instance:ca.getClass().getName())\n"
741: + "}");
742:
743: PicoContainer pico = buildContainer(script, null,
744: ASSEMBLY_SCOPE);
745: // LifecyleContainerBuilder starts the container
746: assertEquals(
747: "org.picocontainer.defaults.CachingComponentAdapter",
748: pico.getComponentInstances().get(1).toString());
749: }
750:
751: private PicoContainer buildContainer(Reader script,
752: PicoContainer parent, Object scope) {
753: return buildContainer(new GroovyContainerBuilder(script,
754: getClass().getClassLoader()), parent, scope);
755: }
756:
757: public void testChainOfDecoratingPicoContainersCanDoInterceptionOfMutablePicoContainerMethods()
758: throws ClassNotFoundException {
759:
760: Reader script = new StringReader(
761: ""
762: + "import org.nanocontainer.testmodel.*\n"
763: + "builder = new org.nanocontainer.script.groovy.GroovyNodeBuilder()\n"
764: + "nano = builder.container {\n"
765: + " decoratingPicoContainer("
766: + FooDecoratingPicoContainer.class.getName()
767: + ")\n" + " decoratingPicoContainer("
768: + BarDecoratingPicoContainer.class.getName()
769: + ")\n"
770: + " component(\"java.util.Vector\")\n" + "}");
771:
772: PicoContainer pico = buildContainer(script, null,
773: ASSEMBLY_SCOPE);
774:
775: // decorators are fairly dirty - they replace a very select implementation in this TestCase.
776: assertNotNull(pico.getComponentInstanceOfType(ArrayList.class));
777: assertNull(pico.getComponentInstanceOfType(Vector.class));
778: }
779:
780: }
|