001: // Copyright 2006, 2007 The Apache Software Foundation
002: //
003: // Licensed under the Apache License, Version 2.0 (the "License");
004: // you may not use this file except in compliance with the License.
005: // You may obtain a copy of the License at
006: //
007: // http://www.apache.org/licenses/LICENSE-2.0
008: //
009: // Unless required by applicable law or agreed to in writing, software
010: // distributed under the License is distributed on an "AS IS" BASIS,
011: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: // See the License for the specific language governing permissions and
013: // limitations under the License.
014:
015: package org.apache.tapestry.internal.model;
016:
017: import java.util.Arrays;
018:
019: import org.apache.commons.logging.Log;
020: import org.apache.tapestry.TapestryConstants;
021: import org.apache.tapestry.internal.test.InternalBaseTestCase;
022: import org.apache.tapestry.ioc.Location;
023: import org.apache.tapestry.ioc.Resource;
024: import org.apache.tapestry.model.ComponentModel;
025: import org.apache.tapestry.model.MutableComponentModel;
026: import org.apache.tapestry.model.MutableEmbeddedComponentModel;
027: import org.apache.tapestry.model.ParameterModel;
028: import org.testng.annotations.Test;
029:
030: /**
031: * Tests {@link org.apache.tapestry.internal.model.MutableComponentModelImpl} and
032: * {@link org.apache.tapestry.internal.model.MutableEmbeddedComponentModelImpl}.
033: */
034: public class MutableComponentModelImplTest extends InternalBaseTestCase {
035: private static final String COMPONENT_CLASS_NAME = "org.example.components.Fred";
036:
037: private static final String CLASS_NAME = "org.example.components.Foo";
038:
039: @Test
040: public void root_class_vs_sub_class() {
041: Resource r = mockResource();
042: Log log = mockLog();
043:
044: replay();
045:
046: MutableComponentModel model = new MutableComponentModelImpl(
047: CLASS_NAME, log, r, null);
048:
049: assertTrue(model.isRootClass());
050:
051: MutableComponentModel subModel = new MutableComponentModelImpl(
052: CLASS_NAME, log, r, model);
053:
054: assertFalse(subModel.isRootClass());
055:
056: verify();
057: }
058:
059: @Test
060: public void add_new_parameter() {
061: Resource r = mockResource();
062: Log log = mockLog();
063:
064: replay();
065:
066: MutableComponentModel model = new MutableComponentModelImpl(
067: CLASS_NAME, log, r, null);
068:
069: assertTrue(model.getParameterNames().isEmpty());
070:
071: String parameterName = "value";
072:
073: model.addParameter(parameterName, true,
074: TapestryConstants.PROP_BINDING_PREFIX);
075:
076: ParameterModel pm = model.getParameterModel(parameterName);
077:
078: assertEquals(pm.getName(), parameterName);
079: assertEquals(true, pm.isRequired());
080: assertEquals(pm.getDefaultBindingPrefix(),
081: TapestryConstants.PROP_BINDING_PREFIX);
082:
083: assertEquals(model.getDeclaredParameterNames(), Arrays
084: .asList(parameterName));
085:
086: // Verify that the binding prefix is actually stored:
087:
088: model.addParameter("fred", true, "flint");
089:
090: // Checks that parameter names are case insensitive
091:
092: assertEquals(model.getParameterModel("Fred")
093: .getDefaultBindingPrefix(), "flint");
094:
095: verify();
096: }
097:
098: @Test
099: public void parameter_names_are_sorted() {
100: Resource r = mockResource();
101: Log log = mockLog();
102:
103: replay();
104:
105: MutableComponentModel model = new MutableComponentModelImpl(
106: CLASS_NAME, log, r, null);
107:
108: model.addParameter("fred", true,
109: TapestryConstants.PROP_BINDING_PREFIX);
110: model.addParameter("wilma", true,
111: TapestryConstants.PROP_BINDING_PREFIX);
112: model.addParameter("barney", true,
113: TapestryConstants.PROP_BINDING_PREFIX);
114:
115: assertEquals(model.getDeclaredParameterNames(), Arrays.asList(
116: "barney", "fred", "wilma"));
117:
118: verify();
119: }
120:
121: @Test
122: public void declared_parameter_names_does_not_include_super class_parameters() {
123: Resource r = mockResource();
124: Log log = mockLog();
125: ComponentModel parent = mockComponentModel();
126:
127: train_getPersistentFieldNames(parent);
128: train_getParameterNames(parent, "betty");
129:
130: replay();
131:
132: MutableComponentModel model = new MutableComponentModelImpl(
133: CLASS_NAME, log, r, parent);
134:
135: model.addParameter("fred", true,
136: TapestryConstants.PROP_BINDING_PREFIX);
137: model.addParameter("wilma", true,
138: TapestryConstants.PROP_BINDING_PREFIX);
139: model.addParameter("barney", true,
140: TapestryConstants.PROP_BINDING_PREFIX);
141:
142: assertEquals(model.getDeclaredParameterNames(), Arrays.asList(
143: "barney", "fred", "wilma"));
144: assertEquals(model.getParameterNames(), Arrays.asList("barney",
145: "betty", "fred", "wilma"));
146:
147: verify();
148: }
149:
150: @Test
151: public void add_duplicate_parameter() {
152: Resource r = mockResource();
153: Log log = mockLog();
154:
155: replay();
156:
157: MutableComponentModel model = new MutableComponentModelImpl(
158: CLASS_NAME, log, r, null);
159:
160: model.addParameter("fred", true,
161: TapestryConstants.PROP_BINDING_PREFIX);
162:
163: try {
164: // This also helps check that the comparison is caseless!
165:
166: model.addParameter("Fred", true,
167: TapestryConstants.PROP_BINDING_PREFIX);
168: unreachable();
169: } catch (IllegalArgumentException ex) {
170: assertEquals(ex.getMessage(),
171: "Parameter 'Fred' of component org.example.components.Foo is already defined.");
172: }
173:
174: verify();
175: }
176:
177: @Test
178: public void get_parameter_by_name_with_no_parameters_defined() {
179: Resource r = mockResource();
180: Log log = mockLog();
181:
182: replay();
183:
184: MutableComponentModel model = new MutableComponentModelImpl(
185: CLASS_NAME, log, r, null);
186:
187: assertNull(model.getParameterModel("foo"));
188:
189: verify();
190: }
191:
192: @Test
193: public void get_unknown_parameter() {
194: Resource r = mockResource();
195: Log log = mockLog();
196:
197: replay();
198:
199: MutableComponentModel model = new MutableComponentModelImpl(
200: CLASS_NAME, log, r, null);
201: model.addParameter("fred", true,
202: TapestryConstants.PROP_BINDING_PREFIX);
203:
204: assertNull(model.getParameterModel("barney"));
205:
206: verify();
207: }
208:
209: @Test
210: public void add_embedded() {
211: Resource r = mockResource();
212: Log log = mockLog();
213: Location l = mockLocation();
214:
215: replay();
216:
217: MutableComponentModel model = new MutableComponentModelImpl(
218: CLASS_NAME, log, r, null);
219:
220: assertTrue(model.getEmbeddedComponentIds().isEmpty());
221:
222: MutableEmbeddedComponentModel fred = model
223: .addEmbeddedComponent("fred", "Fred",
224: COMPONENT_CLASS_NAME, l);
225:
226: assertEquals(fred.getId(), "fred");
227: assertEquals(fred.getComponentType(), "Fred");
228: assertSame(fred.getLocation(), l);
229:
230: MutableEmbeddedComponentModel barney = model
231: .addEmbeddedComponent("barney", "Barney",
232: COMPONENT_CLASS_NAME, null);
233:
234: assertEquals(model.getEmbeddedComponentIds(), Arrays.asList(
235: "barney", "fred"));
236:
237: assertSame(model.getEmbeddedComponentModel("fred"), fred);
238: assertSame(model.getEmbeddedComponentModel("barney"), barney);
239:
240: // Access by id is case insensitive
241:
242: assertSame(model.getEmbeddedComponentModel("FRED"), fred);
243: assertSame(model.getEmbeddedComponentModel("BARNEY"), barney);
244:
245: assertEquals(fred.toString(),
246: "EmbeddedComponentModel[id=fred type=Fred class=org.example.components.Fred]");
247:
248: verify();
249: }
250:
251: @Test
252: public void add_embedded_component_with_duplicate_id() {
253: Resource r = mockResource();
254: Log log = mockLog();
255:
256: replay();
257:
258: MutableComponentModel model = new MutableComponentModelImpl(
259: CLASS_NAME, log, r, null);
260:
261: model.addEmbeddedComponent("fred", "Fred1",
262: COMPONENT_CLASS_NAME, null);
263:
264: try {
265: model.addEmbeddedComponent("fred", "Fred2",
266: COMPONENT_CLASS_NAME, null);
267: unreachable();
268: } catch (IllegalArgumentException ex) {
269: assertEquals(
270: ex.getMessage(),
271: "Embedded component 'fred' has already been defined for component class org.example.components.Foo.");
272: }
273:
274: verify();
275: }
276:
277: @Test
278: public void add_embedded_is_case_insensitive() {
279: Resource r = mockResource();
280: Log log = mockLog();
281:
282: replay();
283:
284: MutableComponentModel model = new MutableComponentModelImpl(
285: CLASS_NAME, log, r, null);
286:
287: model.addEmbeddedComponent("fred", "Fred1",
288: COMPONENT_CLASS_NAME, null);
289:
290: try {
291: model.addEmbeddedComponent("FRED", "Fred2",
292: COMPONENT_CLASS_NAME, null);
293: unreachable();
294: } catch (IllegalArgumentException ex) {
295: assertEquals(
296: ex.getMessage(),
297: "Embedded component 'FRED' has already been defined for component class org.example.components.Foo.");
298: }
299:
300: verify();
301: }
302:
303: @Test
304: public void add_parameters_to_embedded() {
305: Resource r = mockResource();
306: Log log = mockLog();
307:
308: replay();
309:
310: MutableComponentModel model = new MutableComponentModelImpl(
311: CLASS_NAME, log, r, null);
312:
313: MutableEmbeddedComponentModel fred = model
314: .addEmbeddedComponent("fred", "Fred",
315: COMPONENT_CLASS_NAME, null);
316:
317: assertTrue(fred.getParameterNames().isEmpty());
318:
319: fred.addParameter("city", "bedrock");
320: fred.addParameter("job", "crane operator");
321:
322: assertEquals(fred.getParameterNames(), Arrays.asList("city",
323: "job"));
324:
325: assertEquals(fred.getParameterValue("city"), "bedrock");
326:
327: verify();
328: }
329:
330: @Test
331: public void add_duplicate_parameters_to_embedded() {
332: Resource r = mockResource();
333: Log log = mockLog();
334:
335: replay();
336:
337: MutableComponentModel model = new MutableComponentModelImpl(
338: CLASS_NAME, log, r, null);
339:
340: MutableEmbeddedComponentModel fred = model
341: .addEmbeddedComponent("fred", "Fred",
342: COMPONENT_CLASS_NAME, null);
343:
344: fred.addParameter("city", "bedrock");
345:
346: try {
347: fred.addParameter("city", "slateville");
348: unreachable();
349: } catch (IllegalArgumentException ex) {
350: assertEquals(
351: ex.getMessage(),
352: "A value for parameter 'city' of embedded component fred (of component class org.example.components.Foo) has already been provided.");
353: }
354:
355: verify();
356: }
357:
358: @Test
359: public void mixin_names_is_initially_empty_list() {
360: Resource r = mockResource();
361: Log log = mockLog();
362:
363: replay();
364:
365: MutableComponentModel model = new MutableComponentModelImpl(
366: CLASS_NAME, log, r, null);
367:
368: MutableEmbeddedComponentModel fred = model
369: .addEmbeddedComponent("fred", "Fred",
370: COMPONENT_CLASS_NAME, null);
371:
372: assertTrue(fred.getMixinClassNames().isEmpty());
373:
374: verify();
375: }
376:
377: @Test
378: public void mixin_class_names_remembered_in_order_added() {
379: Resource r = mockResource();
380: Log log = mockLog();
381:
382: replay();
383:
384: MutableComponentModel model = new MutableComponentModelImpl(
385: CLASS_NAME, log, r, null);
386:
387: MutableEmbeddedComponentModel fred = model
388: .addEmbeddedComponent("fred", "Fred",
389: COMPONENT_CLASS_NAME, null);
390:
391: fred.addMixin("zip.zop.Zoom");
392: fred.addMixin("foo.bar.Baz");
393:
394: assertEquals(fred.getMixinClassNames(), Arrays.asList(
395: "zip.zop.Zoom", "foo.bar.Baz"));
396:
397: verify();
398: }
399:
400: @Test
401: public void mixin_name_conflict() {
402: Resource r = mockResource();
403: Log log = mockLog();
404:
405: replay();
406:
407: MutableComponentModel model = new MutableComponentModelImpl(
408: CLASS_NAME, log, r, null);
409:
410: MutableEmbeddedComponentModel fred = model
411: .addEmbeddedComponent("fred", "Fred",
412: COMPONENT_CLASS_NAME, null);
413:
414: fred.addMixin("zip.zop.Zoom");
415:
416: try {
417: fred.addMixin("zip.zop.Zoom");
418: unreachable();
419: } catch (IllegalArgumentException ex) {
420: assertEquals(ex.getMessage(),
421: "Mixin zip.zop.Zoom (for component fred) has already been defined.");
422: }
423:
424: // Make sure it wasn't actually added.
425:
426: assertEquals(fred.getMixinClassNames(), Arrays
427: .asList("zip.zop.Zoom"));
428:
429: verify();
430: }
431:
432: @Test
433: public void get_persistent_field_names_when_none_defined() {
434: Resource r = mockResource();
435: Log log = mockLog();
436:
437: replay();
438:
439: MutableComponentModel model = new MutableComponentModelImpl(
440: CLASS_NAME, log, r, null);
441:
442: assertTrue(model.getPersistentFieldNames().isEmpty());
443:
444: verify();
445: }
446:
447: @Test
448: public void get_persistent_field_names_are_sorted() {
449: Resource r = mockResource();
450: Log log = mockLog();
451:
452: replay();
453:
454: MutableComponentModel model = new MutableComponentModelImpl(
455: CLASS_NAME, log, r, null);
456:
457: assertEquals(model.setFieldPersistenceStrategy("fred",
458: "session"), "fred");
459: assertEquals(model.setFieldPersistenceStrategy("barney",
460: "client"), "barney");
461:
462: assertEquals(model.getPersistentFieldNames(), Arrays.asList(
463: "barney", "fred"));
464:
465: verify();
466: }
467:
468: @Test
469: public void persistent_field_names_have_punctuation_stripped() {
470: Resource r = mockResource();
471: Log log = mockLog();
472:
473: replay();
474:
475: MutableComponentModel model = new MutableComponentModelImpl(
476: CLASS_NAME, log, r, null);
477:
478: assertEquals(model.setFieldPersistenceStrategy("_fred",
479: "session"), "fred");
480: assertEquals(model.setFieldPersistenceStrategy("_$barney",
481: "client"), "barney");
482:
483: assertEquals(model.getPersistentFieldNames(), Arrays.asList(
484: "barney", "fred"));
485:
486: verify();
487: }
488:
489: @Test
490: public void get_persistent_field_names_reflects_parent_model() {
491: Resource r = mockResource();
492: Log log = mockLog();
493:
494: replay();
495:
496: MutableComponentModel parent = new MutableComponentModelImpl(
497: CLASS_NAME, log, r, null);
498:
499: assertEquals(parent.setFieldPersistenceStrategy("wilma",
500: "session"), "wilma");
501:
502: MutableComponentModel model = new MutableComponentModelImpl(
503: CLASS_NAME, log, r, parent);
504:
505: assertEquals(model.setFieldPersistenceStrategy("fred",
506: "session"), "fred");
507: assertEquals(model.setFieldPersistenceStrategy("barney",
508: "client"), "barney");
509:
510: assertEquals(model.getPersistentFieldNames(), Arrays.asList(
511: "barney", "fred", "wilma"));
512:
513: verify();
514: }
515:
516: @Test
517: public void persistent_field_names_allocated_in_subclasses_are_unique() {
518: Resource r = mockResource();
519: Log log = mockLog();
520:
521: replay();
522:
523: MutableComponentModel parent = new MutableComponentModelImpl(
524: CLASS_NAME, log, r, null);
525: assertEquals(parent.setFieldPersistenceStrategy("wilma",
526: "session"), "wilma");
527:
528: MutableComponentModel model = new MutableComponentModelImpl(
529: CLASS_NAME, log, r, parent);
530:
531: assertEquals(model.setFieldPersistenceStrategy("wilma",
532: "session"), "wilma_0");
533:
534: assertEquals(model.getPersistentFieldNames(), Arrays.asList(
535: "wilma", "wilma_0"));
536:
537: verify();
538: }
539:
540: @Test
541: public void get_persistent_field_defined_in_model() {
542: Resource r = mockResource();
543: Log log = mockLog();
544:
545: replay();
546:
547: MutableComponentModel model = new MutableComponentModelImpl(
548: CLASS_NAME, log, r, null);
549:
550: model.setFieldPersistenceStrategy("fred", "session");
551: model.setFieldPersistenceStrategy("barney", "client");
552:
553: assertEquals(model.getFieldPersistenceStrategy("fred"),
554: "session");
555: assertEquals(model.getFieldPersistenceStrategy("barney"),
556: "client");
557:
558: verify();
559: }
560:
561: @Test
562: public void no_persistence_defined_for_field() {
563: Resource r = mockResource();
564: Log log = mockLog();
565:
566: replay();
567:
568: MutableComponentModel model = new MutableComponentModelImpl(
569: CLASS_NAME, log, r, null);
570:
571: try {
572: model.getFieldPersistenceStrategy("someField");
573: unreachable();
574: } catch (IllegalArgumentException ex) {
575: assertEquals(ex.getMessage(),
576: "No field persistence strategy has been defined for field \'someField\'.");
577: }
578:
579: verify();
580:
581: }
582:
583: @Test
584: public void get_persistent_field_defined_in_parent() {
585: Resource r = mockResource();
586: Log log = mockLog();
587:
588: replay();
589:
590: MutableComponentModel parent = new MutableComponentModelImpl(
591: CLASS_NAME, log, r, null);
592: MutableComponentModel model = new MutableComponentModelImpl(
593: CLASS_NAME, log, r, parent);
594:
595: parent.setFieldPersistenceStrategy("wilma", "parent");
596:
597: model.setFieldPersistenceStrategy("fred", "session");
598:
599: assertEquals(model.getFieldPersistenceStrategy("wilma"),
600: "parent");
601:
602: verify();
603: }
604:
605: @Test
606: public void default_for_supports_informal_parameters_is_false() {
607: Resource r = mockResource();
608: Log log = mockLog();
609:
610: replay();
611:
612: MutableComponentModel model = new MutableComponentModelImpl(
613: CLASS_NAME, log, r, null);
614:
615: assertFalse(model.getSupportsInformalParameters());
616:
617: model.enableSupportsInformalParameters();
618:
619: assertTrue(model.getSupportsInformalParameters());
620:
621: verify();
622: }
623:
624: @Test
625: public void get_mixin_class_names_with_no_mixins() {
626: Resource r = mockResource();
627: Log log = mockLog();
628:
629: replay();
630: ComponentModel model = new MutableComponentModelImpl(
631: CLASS_NAME, log, r, null);
632:
633: assertTrue(model.getMixinClassNames().isEmpty());
634:
635: verify();
636: }
637:
638: @Test
639: public void get_mixin_class_names_mixes_with_parent_model() {
640: Resource r = mockResource();
641: Log log = mockLog();
642:
643: replay();
644:
645: MutableComponentModel parent = new MutableComponentModelImpl(
646: CLASS_NAME, log, r, null);
647:
648: parent.addMixinClassName("Wilma");
649:
650: MutableComponentModel child = new MutableComponentModelImpl(
651: CLASS_NAME, log, r, parent);
652:
653: child.addMixinClassName("Fred");
654: child.addMixinClassName("Barney");
655:
656: assertEquals(child.getMixinClassNames(), Arrays.asList(
657: "Barney", "Fred", "Wilma"));
658:
659: verify();
660: }
661:
662: @Test
663: public void get_parent_from_subclass() {
664: Resource r = mockResource();
665: Log log = mockLog();
666:
667: replay();
668:
669: MutableComponentModel parent = new MutableComponentModelImpl(
670: CLASS_NAME, log, r, null);
671: MutableComponentModel child = new MutableComponentModelImpl(
672: CLASS_NAME, log, r, parent);
673:
674: assertSame(child.getParentModel(), parent);
675: assertNull(parent.getParentModel());
676:
677: verify();
678: }
679:
680: @Test
681: public void set_and_get_meta() {
682: Resource r = mockResource();
683: Log log = mockLog();
684:
685: replay();
686:
687: MutableComponentModel model = new MutableComponentModelImpl(
688: CLASS_NAME, log, r, null);
689:
690: model.setMeta("fred", "flintstone");
691: model.setMeta("barney", "rubble");
692:
693: assertEquals(model.getMeta("fred"), "flintstone");
694: assertEquals(model.getMeta("barney"), "rubble");
695:
696: // Ensure case insensitive:
697:
698: assertEquals(model.getMeta("FRED"), "flintstone");
699: assertEquals(model.getMeta("BARNEY"), "rubble");
700:
701: verify();
702: }
703:
704: @Test
705: public void get_meta_from_parent() {
706: Resource r = mockResource();
707: Log log = mockLog();
708:
709: replay();
710:
711: MutableComponentModel parent = new MutableComponentModelImpl(
712: CLASS_NAME, log, r, null);
713: MutableComponentModel child = new MutableComponentModelImpl(
714: CLASS_NAME, log, r, parent);
715:
716: parent.setMeta("fred", "flintstone");
717:
718: assertEquals(child.getMeta("fred"), "flintstone");
719:
720: verify();
721: }
722:
723: @Test
724: public void parent_does_not_have_meta() {
725: Resource r = mockResource();
726: Log log = mockLog();
727:
728: replay();
729:
730: MutableComponentModel parent = new MutableComponentModelImpl(
731: CLASS_NAME, log, r, null);
732: MutableComponentModel child = new MutableComponentModelImpl(
733: CLASS_NAME, log, r, parent);
734:
735: parent.setMeta("fred", "flintstone");
736:
737: assertNull(child.getMeta("wilma"));
738:
739: verify();
740: }
741:
742: @Test
743: public void child_meta_overrides_parent_meta() {
744: Resource r = mockResource();
745: Log log = mockLog();
746:
747: replay();
748:
749: MutableComponentModel parent = new MutableComponentModelImpl(
750: CLASS_NAME, log, r, null);
751: MutableComponentModel child = new MutableComponentModelImpl(
752: CLASS_NAME, log, r, parent);
753:
754: parent.setMeta("fred", "flintstone");
755: child.setMeta("fred", "mcmurray");
756:
757: assertEquals(parent.getMeta("fred"), "flintstone");
758: assertEquals(child.getMeta("fred"), "mcmurray");
759:
760: verify();
761: }
762: }
|