1   /*
2    $Id: PropertyTest.java,v 1.16 2004/02/21 08:13:05 jstrachan Exp $
3   
4    Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
5   
6    Redistribution and use of this software and associated documentation
7    ("Software"), with or without modification, are permitted provided
8    that the following conditions are met:
9   
10   1. Redistributions of source code must retain copyright
11      statements and notices.  Redistributions must also contain a
12      copy of this document.
13  
14   2. Redistributions in binary form must reproduce the
15      above copyright notice, this list of conditions and the
16      following disclaimer in the documentation and/or other
17      materials provided with the distribution.
18  
19   3. The name "groovy" must not be used to endorse or promote
20      products derived from this Software without prior written
21      permission of The Codehaus.  For written permission,
22      please contact info@codehaus.org.
23  
24   4. Products derived from this Software may not be called "groovy"
25      nor may "groovy" appear in their names without prior written
26      permission of The Codehaus. "groovy" is a registered
27      trademark of The Codehaus.
28  
29   5. Due credit should be given to The Codehaus -
30      http://groovy.codehaus.org/
31  
32   THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
33   ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
34   NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
35   FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
36   THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
37   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
38   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
39   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
41   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
43   OF THE POSSIBILITY OF SUCH DAMAGE.
44  
45   */
46  
47  package org.codehaus.groovy.runtime;
48  
49  import groovy.lang.Closure;
50  import groovy.lang.MissingMethodException;
51  import groovy.util.GroovyTestCase;
52  import groovy.util.Node;
53  
54  import java.awt.HeadlessException;
55  import java.awt.Point;
56  import java.util.ArrayList;
57  import java.util.HashMap;
58  import java.util.List;
59  import java.util.Map;
60  
61  import javax.swing.JButton;
62  import javax.swing.JFrame;
63  import javax.swing.JPanel;
64  
65  /***
66   * Test the property access of the Invoker class
67   * 
68   * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
69   * @version $Revision: 1.16 $
70   */
71  public class PropertyTest extends GroovyTestCase {
72  
73      protected Invoker invoker = new Invoker();
74  
75      public void testMapProperties() throws Exception {
76          Map map = new HashMap();
77          map.put("foo", "abc");
78          map.put("bar", new Integer(123));
79  
80          assertGetSetProperty(map, "foo", "abc", "def");
81          assertGetSetProperty(map, "bar", new Integer(123), new Double(12.34));
82      }
83  
84      public void testBeanProperties() throws Exception {
85          DummyBean bean = new DummyBean();
86  
87          assertGetSetProperty(bean, "name", "James", "Bob");
88          assertGetSetProperty(bean, "i", new Integer(123), new Integer(455));
89  
90          // dynamic properties
91          assertGetSetProperty(bean, "dynamicFoo", null, "aValue");
92          assertGetSetProperty(bean, "dynamicFoo", "aValue", "NewValue");
93      }
94  
95      public void testUsingMethodProperty() throws Exception {
96          DummyBean bean = new DummyBean();
97  
98          assertGetSetProperty(bean, "name", "James", "Bob");
99  
100         Object value = InvokerHelper.getProperty(bean, "getName");
101         assertTrue("Should have returned a closure: " + value, value instanceof Closure);
102         Closure closure = (Closure) value;
103         Object result = closure.call(null);
104         assertEquals("Result of call to closure", "Bob", result);
105     }
106 
107     public void testStaticProperty() throws Exception {
108         Object value = InvokerHelper.getProperty(System.class, "out");
109         assertEquals("static property out", System.out, value);
110     }
111 
112     public void testClassProperty() throws Exception {
113         Class c = String.class;
114         Object value = InvokerHelper.getProperty(c, "name");
115         assertEquals("class name property", c.getName(), value);
116     }
117 
118     public void testMapEntryProperty() throws Exception {
119         HashMap map = new HashMap();
120         map.put("a", "x");
121         Object[] array = map.entrySet().toArray();
122         Object entry = array[0];
123 
124         Object key = InvokerHelper.getProperty(entry, "key");
125         assertEquals("key property", "a", key);
126 
127         Object value = InvokerHelper.getProperty(entry, "value");
128         assertEquals("value property", "x", value);
129     }
130 
131     public void testMethodProperty() throws Exception {
132         Object value = InvokerHelper.getProperty(this, "getCheese");
133         assertTrue("Should have returned a closure: " + value, value instanceof Closure);
134 
135         Object result = ((Closure) value).call();
136         assertEquals("result of closure call", getCheese(), result);
137 
138         System.out.println("Closure: " + value + " and cheese: " + result);
139     }
140 
141     public void testListCoercionProperty() throws Exception {
142         DummyBean bean = new DummyBean();
143         List list = new ArrayList();
144         list.add(new Integer(10));
145         list.add(new Integer(20));
146 
147         InvokerHelper.setProperty(bean, "point", list);
148         assertEquals("Should have set a point", new Point(10, 20), bean.getPoint());
149     }
150 
151     public void testListCoercionPropertyOnJFrame() throws Exception {
152         try {
153 	        JFrame bean = new JFrame();
154 	        List list = new ArrayList();
155 	        list.add(new Integer(10));
156 	        list.add(new Integer(20));
157 	
158 	        InvokerHelper.setProperty(bean, "location", list);
159 	        assertEquals("Should have set a point", new Point(10, 20), bean.getLocation());
160         }
161         catch (HeadlessException e) {
162             // its fine to not run this test on headless environments
163         }
164         catch (MissingMethodException e) {
165             System.out.println("Failed with cause: " + e);
166             e.printStackTrace();
167             fail("Should not have throw: " + e);
168         }
169     }
170 
171     public void testListNavigationProperty() throws Exception {
172         List list = new ArrayList();
173         list.add(new DummyBean("James"));
174         list.add(new DummyBean("Bob"));
175 
176         List value = (List) InvokerHelper.getProperty(list, "name");
177         assertArrayEquals(new Object[] { "James", "Bob" }, value.toArray());
178     }
179 
180     public void testListOfListNavigationProperty() throws Exception {
181        List list = new ArrayList();
182        list.add(new DummyBean("James"));
183        list.add(new DummyBean("Bob"));
184 
185        List listOfList = new ArrayList();
186        listOfList.add(list);
187        
188        List value = (List) InvokerHelper.getProperty(listOfList, "name");
189        assertArrayEquals(new Object[] { "James", "Bob" }, value.toArray());
190    }
191 
192     public void testNodeNavigationProperty() throws Exception {
193         Node z = new Node(null, "z");
194         Node y = new Node(null, "y");
195 
196         List children = new ArrayList();
197         children.add(y);
198         children.add(z);
199 
200         Node x = new Node(null, "x", children);
201 
202         children = new ArrayList();
203         children.add(x);
204         Node b = new Node(null, "b", children);
205 
206         // @todo should try with just a node as the child
207 
208         List value = (List) InvokerHelper.getProperty(b, "x");
209         assertArrayEquals(new Object[] { x }, value.toArray());
210 
211         value = (List) InvokerHelper.getProperty(value, "z");
212         assertArrayEquals(new Object[] { z }, value.toArray());
213     }
214 
215     public void testUsingInPropertyOnProcessViaGroovyMethod() throws Exception {
216         Process process = DefaultGroovyMethods.execute("java -version");
217         Object value = InvokerHelper.getProperty(process, "in");
218         assertNotNull(value);
219         
220         System.out.println("Found in: " + value);
221         
222         process.destroy();
223     }
224     
225     public Object getCheese() {
226         return "cheddar";
227     }
228 
229     public void testComponentParent() {
230         JPanel panel = new JPanel();
231         JButton bean = new JButton();
232         
233         panel.add(bean);
234         
235         Object value = InvokerHelper.getProperty(bean, "parent");
236         assertTrue(value != null);
237     }
238     
239     // Implementation methods
240     //-------------------------------------------------------------------------
241 
242     protected void assertGetSetProperty(Object object, String property, Object currentValue, Object newValue) {
243         assertGetProperty(object, property, currentValue);
244 
245         InvokerHelper.setProperty(object, property, newValue);
246 
247         assertGetProperty(object, property, newValue);
248     }
249 
250     protected void assertGetProperty(Object object, String property, Object expected) {
251         Object value = InvokerHelper.getProperty(object, property);
252 
253         assertEquals("property: " + property + " of: " + object, expected, value);
254     }
255 }