001 // Copyright 2004, 2005 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.junit.parse; 016 017 import org.apache.commons.logging.Log; 018 import org.apache.hivemind.Locatable; 019 import org.apache.hivemind.Resource; 020 import org.apache.hivemind.impl.DefaultClassResolver; 021 import org.apache.hivemind.impl.DefaultErrorHandler; 022 import org.apache.tapestry.bean.BindingBeanInitializer; 023 import org.apache.tapestry.bean.LightweightBeanInitializer; 024 import org.apache.tapestry.junit.TapestryTestCase; 025 import org.apache.tapestry.parse.SpecificationParser; 026 import org.apache.tapestry.spec.*; 027 import org.apache.tapestry.util.xml.DocumentParseException; 028 import org.testng.annotations.Test; 029 030 import java.util.List; 031 032 /** 033 * Tests the specification parser (which reads page and component specifications). Came into being 034 * somewhat late, so it just tests new features for the meantime. 035 * 036 * @author Howard Lewis Ship 037 * @since 2.0.4 038 */ 039 @Test 040 public class TestSpecificationParser extends TapestryTestCase 041 { 042 043 private void checkLine(Locatable locatable, int line) 044 { 045 assertEquals(line, locatable.getLocation().getLineNumber()); 046 } 047 048 /** 049 * Test 3.0 <message-binding> element. 050 */ 051 052 public void tes_Message_Binding() throws Exception 053 { 054 IComponentSpecification spec = parseComponent("TestMessageBinding.jwc"); 055 056 IBindingSpecification bs = spec.getComponent("hello").getBinding("value"); 057 058 assertEquals(BindingType.PREFIXED, bs.getType()); 059 assertEquals("message:label.hello", bs.getValue()); 060 061 checkLine(bs, 25); 062 } 063 064 /** 065 * Tests the 4.0 style <binding> element. 066 */ 067 068 public void testBinding40() throws Exception 069 { 070 IComponentSpecification spec = parseComponent("Binding40.jwc"); 071 IContainedComponent cc = spec.getComponent("component"); 072 073 IBindingSpecification bs = cc.getBinding("simple"); 074 075 assertEquals(BindingType.PREFIXED, bs.getType()); 076 assertEquals("message:some-key", bs.getValue()); 077 078 bs = cc.getBinding("enclosed"); 079 080 assertEquals(BindingType.PREFIXED, bs.getType()); 081 assertEquals("ognl:zip.zap.zoop", bs.getValue()); 082 } 083 084 /** 085 * Test valid parameter name. 086 * 087 * @since 2.2 088 */ 089 090 public void testValidParameterName() throws Exception 091 { 092 IComponentSpecification spec = parseComponent("ValidParameterName.jwc"); 093 094 IParameterSpecification ps = spec.getParameter("valid"); 095 096 assertNotNull(ps); 097 checkLine(ps, 24); 098 } 099 100 /** 101 * Test invalid parameter name. 102 * 103 * @since 2.2 104 */ 105 106 public void testInvalidParameterName() throws Exception 107 { 108 try 109 { 110 parseComponent("InvalidParameterName.jwc"); 111 112 unreachable(); 113 } 114 catch (DocumentParseException ex) 115 { 116 checkException(ex, "in-valid"); 117 checkException(ex, "Parameter"); 118 } 119 } 120 121 /** 122 * Test invalid component id. 123 * 124 * @since 2.2 125 */ 126 127 public void testInvalidComponentId() throws Exception 128 { 129 try 130 { 131 parseComponent("InvalidComponentId.jwc"); 132 133 unreachable(); 134 } 135 catch (DocumentParseException ex) 136 { 137 checkException(ex, "in.valid"); 138 checkException(ex, "component id"); 139 } 140 } 141 142 /** 143 * Test invalid library id in a library specification. 144 * 145 * @since 2.2 146 */ 147 148 public void testInvalidLibraryId() throws Exception 149 { 150 try 151 { 152 parseLib("InvalidLibraryId.library"); 153 154 unreachable(); 155 } 156 catch (DocumentParseException ex) 157 { 158 checkException(ex, "in.valid"); 159 checkException(ex, "library id"); 160 } 161 } 162 163 /** 164 * Parse a valid library. 165 * 166 * @since 2.2 167 */ 168 169 public void testValidLibrary() throws Exception 170 { 171 ILibrarySpecification spec = parseLib("ValidLibrary.library"); 172 173 checkLine(spec, 24); 174 175 checkList("pageNames", new String[] 176 { "FirstPage", "SecondPage" }, spec.getPageNames()); 177 178 checkList("componentAliases", new String[] 179 { "FirstComponent", "SecondComponent" }, spec.getComponentTypes()); 180 181 checkList("libraryIds", new String[] 182 { "lib1", "lib2" }, spec.getLibraryIds()); 183 184 assertNotNull(spec.getSpecificationLocation()); 185 } 186 187 /** 188 * Test invalid parameter name. 189 * 190 * @since 2.2 191 */ 192 193 public void testInvalidAssetName() throws Exception 194 { 195 try 196 { 197 parseComponent("InvalidAssetName.jwc"); 198 199 unreachable(); 200 } 201 catch (DocumentParseException ex) 202 { 203 checkException(ex, "in.valid"); 204 checkException(ex, "asset name"); 205 } 206 } 207 208 /** 209 * Test invalid page name. 210 * 211 * @since 2.2 212 */ 213 214 public void testInvalidPageName() throws Exception 215 { 216 try 217 { 218 parseApp("InvalidPageName.application"); 219 220 unreachable(); 221 } 222 catch (DocumentParseException ex) 223 { 224 checkException(ex, "in$valid"); 225 checkException(ex, "page name"); 226 } 227 } 228 229 /** 230 * Test invalid component type ("alias" in older parlance). 231 * 232 * @since 2.2 233 */ 234 235 public void testInvalidComponentAlias() throws Exception 236 { 237 try 238 { 239 parseApp("InvalidComponentAlias.application"); 240 241 unreachable(); 242 } 243 catch (DocumentParseException ex) 244 { 245 checkException(ex, "Invalid$Component"); 246 checkException(ex, "type"); 247 } 248 } 249 250 /** 251 * Test invalid extension name. 252 * 253 * @since 2.2 254 */ 255 256 public void testInvalidExtensionName() throws Exception 257 { 258 try 259 { 260 parseApp("InvalidExtensionName.application"); 261 262 unreachable(); 263 } 264 catch (DocumentParseException ex) 265 { 266 checkException(ex, "Invalid$Extension"); 267 checkException(ex, "extension name"); 268 } 269 } 270 271 public void test_Malformed_Xml_Tag() throws Exception 272 { 273 try 274 { 275 parsePage("MalformedXmlTag.page"); 276 277 unreachable(); 278 } 279 catch (DocumentParseException ex) 280 { 281 checkException(ex, "Element type \"binding\" must be followed by either attribute"); 282 } 283 } 284 285 /** 286 * Test case where the document does not have a DOCTYPE 287 * 288 * @since 2.2 289 */ 290 291 public void testMissingDoctype() throws Exception 292 { 293 try 294 { 295 parseApp("MissingDoctype.application"); 296 297 unreachable(); 298 } 299 catch (DocumentParseException ex) 300 { 301 // XML parsers tend to generate different exception messages, 302 // so make the condition as unspecific as possible 303 checkException(ex, "DOCTYPE"); 304 } 305 } 306 307 /** 308 * Test case where the public id of the document is not known. 309 */ 310 311 public void testInvalidPublicId() throws Exception 312 { 313 try 314 { 315 parseApp("InvalidPublicId.application"); 316 317 unreachable(); 318 } 319 catch (DocumentParseException ex) 320 { 321 checkException(ex, "has an unexpected public id"); 322 } 323 } 324 325 /** 326 * Test an an application specification can omit the name and engine-class attributes. 327 * 328 * @since 3.0 329 */ 330 331 public void testNulledApplication() throws Exception 332 { 333 IApplicationSpecification spec = parseApp("NulledApplication.application"); 334 335 assertNull(spec.getEngineClassName()); 336 assertNull(spec.getName()); 337 checkLine(spec, 25); 338 339 assertNotNull(spec.getSpecificationLocation()); 340 } 341 342 /** 343 * Test new DTD 1.4 syntax for declaring components. 344 * 345 * @since 3.0 346 */ 347 348 public void testComponentType() throws Exception 349 { 350 IApplicationSpecification spec = parseApp("ComponentType.application"); 351 352 assertEquals("/path/Fred.jwc", spec.getComponentSpecificationPath("Fred")); 353 } 354 355 /** 356 * Test omitting the class name from a component specification (new, in DTD 1.4). 357 */ 358 359 public void testNulledComponent() throws Exception 360 { 361 IComponentSpecification spec = parseComponent("NulledComponent.jwc"); 362 363 assertNull(spec.getComponentClassName()); 364 checkLine(spec, 22); 365 366 assertEquals(false, spec.isPageSpecification()); 367 assertNotNull(spec.getSpecificationLocation()); 368 369 assertEquals(false, spec.isDeprecated()); 370 } 371 372 /** 373 * Test omitting the class name from a component specification (new, in DTD 1.4). 374 */ 375 376 public void testNulledPage() throws Exception 377 { 378 IComponentSpecification spec = parsePage("NulledPage.page"); 379 380 assertNull(spec.getComponentClassName()); 381 checkLine(spec, 22); 382 383 assertEquals(true, spec.isPageSpecification()); 384 assertNotNull(spec.getSpecificationLocation()); 385 } 386 387 /** 388 * Test the value attribute for the property element (which is new in DTD 1.4). 389 * 390 * @since 3.0 391 */ 392 393 public void testPropertyValue() throws Exception 394 { 395 IComponentSpecification spec = parsePage("PropertyValue.page"); 396 397 checkLine(spec, 22); 398 399 assertEquals("rubble", spec.getProperty("barney")); 400 assertEquals("flintstone", spec.getProperty("wilma")); 401 } 402 403 /** 404 * Tests the new (in DTD 1.4) value attribute on static-binding element. 405 * 406 * @since 3.0 407 */ 408 409 public void testStaticBindingValue() throws Exception 410 { 411 IComponentSpecification spec = parsePage("StaticBindingValue.page"); 412 413 checkLine(spec, 22); 414 415 IContainedComponent c = spec.getComponent("c"); 416 417 checkLine(c, 24); 418 419 IBindingSpecification b = c.getBinding("fred"); 420 checkLine(b, 25); 421 422 assertEquals("literal:flintstone", b.getValue()); 423 424 b = c.getBinding("barney"); 425 checkLine(b, 26); 426 427 assertEquals("literal:rubble", b.getValue()); 428 429 b = c.getBinding("rock"); 430 checkLine(b, 27); 431 assertEquals("literal:hudson", b.getValue()); 432 } 433 434 public void testAttributeAndBody() throws Exception 435 { 436 try 437 { 438 parsePage("AttributeAndBody.page"); 439 440 unreachable(); 441 } 442 catch (DocumentParseException ex) 443 { 444 checkException( 445 ex, 446 "It is not valid to specify a value for attribute 'value' of <static-binding> and provide a value in the body of the element."); 447 } 448 } 449 450 /** 451 * Tests the new (in DTD 1.4) value attribute on a configure element. 452 * 453 * @since 3.0 454 */ 455 456 public void testConfigureValue() throws Exception 457 { 458 ILibrarySpecification spec = parseLib("ConfigureValue.library"); 459 460 checkLine(spec, 22); 461 checkLine(spec.getExtensionSpecification("bedrock"), 24); 462 463 Bedrock bedrock = (Bedrock) spec.getExtension("bedrock", Bedrock.class); 464 465 assertEquals("flintstone", bedrock.getFred()); 466 } 467 468 /** 469 * Tests the new <listener-binding> element in the 1.4 DTD. 470 * 471 * @since 3.0 472 */ 473 474 public void testListenerBinding() throws Exception 475 { 476 Log log = newMock(Log.class); 477 478 SpecificationParser parser = new SpecificationParser(new DefaultErrorHandler(), log, 479 new DefaultClassResolver(), new SpecFactory()); 480 481 parser.setBindingSource(newBindingSource()); 482 483 Resource location = getSpecificationResourceLocation("ListenerBinding.page"); 484 485 log 486 .warn("The <listener-binding> element is no longer supported (at classpath:/org/apache/tapestry/junit/parse/ListenerBinding.page, line 25, column 56)."); 487 488 replay(); 489 490 IComponentSpecification spec = parser.parsePageSpecification(location); 491 492 verify(); 493 494 IContainedComponent cc = spec.getComponent("c"); 495 496 assertNull(cc.getBinding("listener")); 497 498 IBindingSpecification bs = cc.getBinding("foo"); 499 500 assertEquals(BindingType.PREFIXED, bs.getType()); 501 assertEquals("literal:bar", bs.getValue()); 502 } 503 504 /** @since 3.0 * */ 505 506 public void testPropertySpecifications() throws Exception 507 { 508 IComponentSpecification spec = parsePage("PropertySpecifications.page"); 509 510 checkList("propertySpecificationNames", new String[] 511 { "bool", "init", "longInitialValue", "persist" }, spec.getPropertySpecificationNames()); 512 513 IPropertySpecification ps = spec.getPropertySpecification("bool"); 514 assertEquals("bool", ps.getName()); 515 assertEquals(false, ps.isPersistent()); 516 assertEquals("boolean", ps.getType()); 517 assertNull(ps.getInitialValue()); 518 checkLine(ps, 24); 519 520 ps = spec.getPropertySpecification("init"); 521 assertEquals("init", ps.getName()); 522 assertEquals(false, ps.isPersistent()); 523 assertNull(ps.getType()); 524 525 // Starting with release 4.0, the initial value is a binding reference 526 // with an appropriate prefix. In 3.0 it was always an OGNL expression. 527 528 assertEquals("ognl:pageName", ps.getInitialValue()); 529 checkLine(ps, 26); 530 531 ps = spec.getPropertySpecification("persist"); 532 assertEquals("persist", ps.getName()); 533 assertEquals(true, ps.isPersistent()); 534 assertNull(ps.getType()); 535 assertNull(ps.getInitialValue()); 536 checkLine(ps, 25); 537 538 ps = spec.getPropertySpecification("longInitialValue"); 539 assertEquals("ognl:long.initial.value", ps.getInitialValue()); 540 541 ps = spec.getPropertySpecification("unknown"); 542 543 assertNull(ps); 544 } 545 546 /** @since 3.0 * */ 547 548 public void testMissingRequiredExtendedAttribute() throws Exception 549 { 550 try 551 { 552 parsePage("MissingRequiredExtendedAttribute.page"); 553 554 unreachable(); 555 } 556 catch (DocumentParseException ex) 557 { 558 checkException( 559 ex, 560 "Element <binding> does not specify a value for attribute 'expression', or contain a body value."); 561 } 562 } 563 564 /** @since 3.0 * */ 565 566 public void testMessageBeanInitializer() throws Exception 567 { 568 IComponentSpecification spec = parsePage("MessageBeanInitializer.page"); 569 570 IBeanSpecification bs = spec.getBeanSpecification("fred"); 571 checkLine(bs, 24); 572 BindingBeanInitializer i = (BindingBeanInitializer) bs.getInitializers().get(0); 573 574 assertEquals("barney", i.getPropertyName()); 575 assertEquals("message:rubble", i.getBindingReference()); 576 checkLine(i, 25); 577 } 578 579 /** 580 * Tests the DTD 3.0 <set-property>element 581 * 582 * @since 4.0 583 */ 584 585 public void testExpressionBeanInitializer() throws Exception 586 { 587 IComponentSpecification spec = parsePage("ExpressionBeanInitializer_3_0.page"); 588 589 IBeanSpecification bs = spec.getBeanSpecification("zebean"); 590 591 BindingBeanInitializer i = (BindingBeanInitializer) bs.getInitializers().get(0); 592 593 assertEquals("barney", i.getPropertyName()); 594 assertEquals("ognl:rubble", i.getBindingReference()); 595 596 i = (BindingBeanInitializer) bs.getInitializers().get(1); 597 598 assertEquals("fred", i.getPropertyName()); 599 assertEquals("ognl:flintstone", i.getBindingReference()); 600 } 601 602 /** @since 4.0 */ 603 604 public void testBeanSet() throws Exception 605 { 606 IComponentSpecification spec = parsePage("BeanSet.page"); 607 IBeanSpecification bs = spec.getBeanSpecification("target"); 608 609 BindingBeanInitializer i = (BindingBeanInitializer) bs.getInitializers().get(0); 610 611 assertEquals("literal", i.getPropertyName()); 612 assertEquals("literal-string", i.getBindingReference()); 613 614 } 615 616 public void testInheritInformalParameters() throws Exception 617 { 618 IComponentSpecification spec = parseComponent("TestInheritInformal.jwc"); 619 620 IContainedComponent border = spec.getComponent("border"); 621 assertEquals(border.getInheritInformalParameters(), false); 622 623 IContainedComponent textField = spec.getComponent("textField"); 624 assertEquals(textField.getInheritInformalParameters(), true); 625 } 626 627 /** @since 4.0 */ 628 629 public void testConfigureExtension() throws Exception 630 { 631 IApplicationSpecification spec = parseApp("ConfigureExtension.application"); 632 IExtensionSpecification es = spec.getExtensionSpecification("my-extension"); 633 634 // Note: this is in transition; under 3.0 and earlier, the spec parser was 635 // responsible for converting values into object types ... that is now 636 // done futher down stream. 637 638 assertEquals("-227", es.getConfiguration().get("long")); 639 assertEquals("22.7", es.getConfiguration().get("double")); 640 assertEquals("true", es.getConfiguration().get("boolean")); 641 assertEquals("An extended string.", es.getConfiguration().get("string")); 642 } 643 644 public void testConfigureExtensionProperty() throws Exception 645 { 646 IApplicationSpecification spec = parseApp("ConfigureExtension.application"); 647 IExtensionSpecification es = spec.getExtensionSpecification("my-extension"); 648 649 assertEquals("my-value", es.getProperty("my-property")); 650 } 651 652 /** @since 4.0 */ 653 654 public void testComponentProperty() throws Exception 655 { 656 IComponentSpecification cs = parseComponent("ComponentProperty.jwc"); 657 658 IContainedComponent cc = cs.getComponent("body"); 659 660 assertEquals("my-value", cc.getProperty("my-property")); 661 } 662 663 /** @since 4.0 */ 664 665 public void testComponentInjectProperty() throws Exception 666 { 667 IComponentSpecification cs = parseComponent("ComponentInjectProperty.jwc"); 668 669 IContainedComponent cc = cs.getComponent("body"); 670 671 assertEquals("myProperty", cc.getPropertyName()); 672 673 cc = cs.getComponent("fred"); 674 675 assertNull(cc.getPropertyName()); 676 } 677 678 /** @since 4.0 */ 679 680 public void testBeanDescription() throws Exception 681 { 682 IComponentSpecification cs = parseComponent("BeanDescription.jwc"); 683 IBeanSpecification bs = cs.getBeanSpecification("mybean"); 684 685 assertEquals("Description of mybean.", bs.getDescription()); 686 assertNotNull(bs.getLocation()); 687 } 688 689 /** @since 4.0 */ 690 691 public void testBeanProperty() throws Exception 692 { 693 IComponentSpecification cs = parseComponent("BeanDescription.jwc"); 694 IBeanSpecification bs = cs.getBeanSpecification("mybean"); 695 696 assertEquals("myvalue", bs.getProperty("myproperty")); 697 } 698 699 /** 700 * @since 4.0 701 */ 702 703 public void testBeanInject() throws Exception 704 { 705 IComponentSpecification cs = parseComponent("BeanInject.jwc"); 706 IBeanSpecification bs = cs.getBeanSpecification("bean"); 707 assertEquals("myProperty", bs.getPropertyName()); 708 } 709 710 /** 711 * @since 4.0 712 */ 713 714 public void testBeanInitializer() throws Exception 715 { 716 IComponentSpecification cs = parseComponent("BeanInitializer.jwc"); 717 IBeanSpecification bs = cs.getBeanSpecification("bean"); 718 719 List l = bs.getInitializers(); 720 LightweightBeanInitializer lbi = (LightweightBeanInitializer) l.get(0); 721 722 assertEquals("foo=bar", lbi.getPropertyName()); 723 } 724 725 /** @since 4.0 */ 726 727 public void testLibraryDescription() throws Exception 728 { 729 ILibrarySpecification ls = parseLib("LibraryDescription.library"); 730 731 assertEquals("Often, these are just placeholders.", ls.getDescription()); 732 } 733 734 /** @since 4.0 */ 735 736 public void testPageDescription() throws Exception 737 { 738 IComponentSpecification spec = parsePage("PageDescription.page"); 739 740 assertEquals("Description of this page.", spec.getDescription()); 741 } 742 743 /** 744 * Excercies the check that the correct root element is used. 745 * 746 * @since 4.0 747 */ 748 749 public void testRootElementMismatch() throws Exception 750 { 751 try 752 { 753 parseComponent("NulledPage.page"); 754 unreachable(); 755 } 756 catch (Exception ex) 757 { 758 checkException( 759 ex, 760 "Incorrect document type; expected page-specification but received component-specification."); 761 } 762 } 763 764 /** 765 * Checks to make sure that a application or library may not defined a lbirary with id 766 * 'framework'. 767 * 768 * @since 4.0 769 */ 770 771 public void testLibraryFrameworkNamespace() throws Exception 772 { 773 try 774 { 775 parseLib("LibraryFrameworkNamespace.library"); 776 unreachable(); 777 } 778 catch (Exception ex) 779 { 780 checkException(ex, "The library id 'framework' is reserved and may not be used."); 781 } 782 } 783 784 /** 785 * Tests that a <component> element may not have both type and copy-of attributes. 786 * 787 * @since 4.0 788 */ 789 790 public void testComponentWithTypeAndCopyOf() throws Exception 791 { 792 try 793 { 794 parseComponent("ComponentWithTypeAndCopyOf.jwc"); 795 unreachable(); 796 } 797 catch (Exception ex) 798 { 799 checkException(ex, "Contained component bad contains both type and copy-of attributes."); 800 } 801 } 802 803 /** 804 * Tests that <component> must have either type or copy-of attribute. 805 * 806 * @since 4.0 807 */ 808 809 public void testComponentWithoutType() throws Exception 810 { 811 try 812 { 813 parseComponent("ComponentWithoutType.jwc"); 814 unreachable(); 815 } 816 catch (Exception ex) 817 { 818 checkException( 819 ex, 820 "Contained component bad does not specify attribute type or copy-of."); 821 } 822 } 823 824 /** 825 * Tests the use of copy-of attribute inside <component>. 826 * 827 * @since 4.0 828 */ 829 830 public void testComponentCopyOf() throws Exception 831 { 832 IComponentSpecification cs = parseComponent("ComponentCopyOf.jwc"); 833 834 IContainedComponent source = cs.getComponent("source"); 835 IContainedComponent copy = cs.getComponent("copy"); 836 IContainedComponent override = cs.getComponent("override"); 837 838 assertEquals("Insert", source.getType()); 839 assertEquals("Insert", copy.getType()); 840 assertEquals("Insert", override.getType()); 841 842 IBindingSpecification b = source.getBinding("value"); 843 844 assertEquals(BindingType.PREFIXED, b.getType()); 845 assertEquals("ognl:date", b.getValue()); 846 847 assertSame(b, copy.getBinding("value")); 848 849 IBindingSpecification b2 = override.getBinding("value"); 850 assertEquals("ognl:tomorrow", b2.getValue()); 851 852 b = copy.getBinding("foo"); 853 854 assertSame(b, override.getBinding("foo")); 855 856 b = copy.getBinding("formatter"); 857 858 assertSame(b, override.getBinding("formatter")); 859 } 860 861 /** 862 * And here's what happens when copy-of doesn't match a known component. 863 * 864 * @since 4.0 865 */ 866 public void testComponentBadCopy() 867 { 868 try 869 { 870 parseComponent("ComponentBadCopy.jwc"); 871 unreachable(); 872 } 873 catch (Exception ex) 874 { 875 checkException(ex, "Unable to copy component missing, which does not exist."); 876 } 877 } 878 879 /** @since 4.0 */ 880 public void testMeta() throws Exception 881 { 882 ILibrarySpecification spec = parseLib("Meta.library"); 883 884 assertEquals("bar", spec.getProperty("foo")); 885 assertEquals("long value", spec.getProperty("long")); 886 } 887 888 /** @since 4.0 */ 889 public void testInject() throws Exception 890 { 891 IComponentSpecification spec = parseComponent("Inject.jwc"); 892 893 List l = spec.getInjectSpecifications(); 894 895 assertEquals(2, l.size()); 896 897 InjectSpecification i1 = (InjectSpecification) l.get(0); 898 899 assertEquals("fred", i1.getProperty()); 900 assertEquals("object", i1.getType()); 901 assertEquals("flintstone", i1.getObject()); 902 assertNotNull(i1.getLocation()); 903 904 InjectSpecification i2 = (InjectSpecification) l.get(1); 905 assertEquals("barney", i2.getProperty()); 906 assertEquals("state", i2.getType()); 907 assertEquals("rubble", i2.getObject()); 908 assertNotNull(i2.getLocation()); 909 } 910 911 /** 912 * Test that the new <property> element (was <property-specification> in release 913 * 3.0) works correctly. 914 * 915 * @since 4.0 916 */ 917 918 public void testProperty() throws Exception 919 { 920 IComponentSpecification spec = parsePage("Property.page"); 921 922 checkList("propertySpecificationNames", new String[] 923 { "bool", "init", "longInit", "persist" }, spec.getPropertySpecificationNames()); 924 925 IPropertySpecification ps = spec.getPropertySpecification("bool"); 926 assertEquals("bool", ps.getName()); 927 assertEquals(false, ps.isPersistent()); 928 929 // In a 4.0 DTD, type is always null. 930 assertNull(ps.getType()); 931 932 // Note that no prefix is added. Initial value will be a string literal, 933 // or have a prefix and be something else. 934 935 assertNull(ps.getInitialValue()); 936 checkLine(ps, 24); 937 938 ps = spec.getPropertySpecification("init"); 939 assertEquals("init", ps.getName()); 940 assertEquals(false, ps.isPersistent()); 941 942 assertEquals("ognl:pageName", ps.getInitialValue()); 943 checkLine(ps, 26); 944 945 ps = spec.getPropertySpecification("persist"); 946 assertEquals("persist", ps.getName()); 947 assertEquals(true, ps.isPersistent()); 948 assertNull(ps.getInitialValue()); 949 checkLine(ps, 25); 950 951 ps = spec.getPropertySpecification("longInit"); 952 assertEquals("message:long-init-key", ps.getInitialValue()); 953 954 ps = spec.getPropertySpecification("unknown"); 955 956 assertNull(ps); 957 } 958 959 /** 960 * Tests parameters specification from a 3.0 DTD 961 * 962 * @since 4.0 963 */ 964 965 public void testParameter_3_0() throws Exception 966 { 967 IComponentSpecification spec = parseComponent("Parameter_3_0.jwc"); 968 969 IParameterSpecification ps = spec.getParameter("noDefault"); 970 971 assertEquals("noDefault", ps.getPropertyName()); 972 assertEquals("noDefault", ps.getParameterName()); 973 assertEquals(true, ps.isRequired()); 974 assertEquals("bar", ps.getType()); 975 assertNull(ps.getDefaultValue()); 976 assertEquals(false, ps.isDeprecated()); 977 978 ps = spec.getParameter("withDefault"); 979 assertEquals("withDefault", ps.getParameterName()); 980 assertNull(ps.getType()); 981 assertEquals(false, ps.isRequired()); 982 983 // For 3.0 DTDs, where the default value was always an OGNL expression, 984 // the parser will provide the "ognl:" prefix. 985 986 assertEquals("ognl:an.expression", ps.getDefaultValue()); 987 988 ps = spec.getParameter("withDescription"); 989 assertEquals("A parameter with a description.", ps.getDescription()); 990 991 ps = spec.getParameter("altName"); 992 assertEquals("altNameParameter", ps.getPropertyName()); 993 994 ps = spec.getParameter("directionIn"); 995 assertEquals(true, ps.getCache()); 996 997 ps = spec.getParameter("directionAuto"); 998 assertEquals(false, ps.getCache()); 999 } 1000 1001 /** 1002 * Tests the new way default-value is interpreted (as a binding-like value, prefixed to indicate 1003 * type). 1004 * 1005 * @since 4.0 1006 */ 1007 1008 public void testParameter() throws Exception 1009 { 1010 IComponentSpecification spec = parseComponent("Parameter.jwc"); 1011 1012 IParameterSpecification ps = spec.getParameter("noDefault"); 1013 1014 assertNull(ps.getDefaultValue()); 1015 assertEquals(true, ps.getCache()); 1016 assertTrue(ps.getAliasNames().isEmpty()); 1017 assertEquals(false, ps.isDeprecated()); 1018 1019 ps = spec.getParameter("literalDefault"); 1020 1021 assertEquals("literal-value", ps.getDefaultValue()); 1022 1023 ps = spec.getParameter("expressionDefault"); 1024 1025 assertEquals("ognl:an.expression", ps.getDefaultValue()); 1026 1027 ps = spec.getParameter("noCache"); 1028 assertEquals(false, ps.getCache()); 1029 1030 ps = spec.getParameter("withAliases"); 1031 assertListEquals(new String[] 1032 { "fred", "barney" }, ps.getAliasNames().toArray()); 1033 1034 assertSame(ps, spec.getParameter("fred")); 1035 assertSame(ps, spec.getParameter("barney")); 1036 1037 ps = spec.getParameter("deprecated"); 1038 assertEquals(true, ps.isDeprecated()); 1039 } 1040 1041 /** 1042 * Tests that assets read using the 3.0 DTD are converted properly into paths with the proper 1043 * prefix. 1044 * 1045 * @since 4.0 1046 */ 1047 public void testAssets_3_0() throws Exception 1048 { 1049 IComponentSpecification cs = parsePage("Assets_3_0.page"); 1050 1051 IAssetSpecification as = cs.getAsset("mycontext"); 1052 1053 assertEquals("context:path/to/context", as.getPath()); 1054 1055 as = cs.getAsset("myprivate"); 1056 1057 assertEquals("classpath:path/to/private", as.getPath()); 1058 1059 as = cs.getAsset("myexternal"); 1060 1061 assertEquals("http://myexternal/asset", as.getPath()); 1062 1063 assertListEquals(new String[] 1064 { "mycontext", "myexternal", "myprivate" }, cs.getAssetNames()); 1065 } 1066 1067 /** @since 4.0 */ 1068 1069 public void testAssets() throws Exception 1070 { 1071 IComponentSpecification cs = parsePage("Assets.page"); 1072 1073 IAssetSpecification as = cs.getAsset("myasset"); 1074 1075 assertEquals("path/to/asset", as.getPath()); 1076 assertEquals("myProperty", as.getPropertyName()); 1077 } 1078 1079 /** @since 4.0 */ 1080 1081 public void testDeprecatedComponent() throws Exception 1082 { 1083 IComponentSpecification cs = parseComponent("DeprecatedComponent.jwc"); 1084 1085 assertEquals(true, cs.isDeprecated()); 1086 } 1087 1088 /** @since 4.0 */ 1089 1090 public void testLibrarySlashInComponentType() throws Exception 1091 { 1092 ILibrarySpecification ls = parseLib("SlashInComponentType.library"); 1093 1094 List types = ls.getComponentTypes(); 1095 1096 assertEquals(1, types.size()); 1097 1098 assertEquals("foo/Bar", types.get(0)); 1099 1100 assertEquals("foocomponents/BarComponent.jwc", ls.getComponentSpecificationPath("foo/Bar")); 1101 } 1102 1103 /** @since 4.0 */ 1104 1105 public void testComponentSlashInComponentType() throws Exception 1106 { 1107 IComponentSpecification cs = parseComponent("SlashInComponentType.jwc"); 1108 1109 IContainedComponent cc = cs.getComponent("fred"); 1110 1111 assertEquals("rubble/Barney", cc.getType()); 1112 } 1113 }