001    // Copyright 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.describe;
016    
017    import static org.easymock.EasyMock.expect;
018    
019    import java.util.ArrayList;
020    import java.util.Arrays;
021    import java.util.Collection;
022    import java.util.Collections;
023    import java.util.List;
024    
025    import org.apache.tapestry.IMarkupWriter;
026    import org.testng.annotations.Test;
027    
028    /**
029     * Tests for {@link org.apache.tapestry.describe.HTMLDescriptionReceiver}and
030     * {@link org.apache.tapestry.describe.HTMLDescriberImpl}.
031     * 
032     * @author Howard M. Lewis Ship
033     * @since 4.0
034     */
035    @Test(sequential = true)
036    public class HTMLDescriptionReceiverTest extends BaseDescribeTestCase
037    {
038        protected DescribableStrategy newStrategy()
039        {
040            return newMock(DescribableStrategy.class);
041        }
042    
043        private void trainForTitle(IMarkupWriter writer, String title)
044        {
045            writer.begin("div");
046            writer.attribute("class", "described-object-title");
047            writer.print(title);
048            writer.end();
049            writer.println();
050    
051            writer.begin("table");
052            writer.attribute("class", "described-object");
053            writer.println();
054        }
055    
056        private void trainForSection(IMarkupWriter writer, String section)
057        {
058            writer.begin("tr");
059            writer.attribute("class", "section");
060            writer.begin("th");
061            writer.attribute("colspan", 2);
062            writer.print(section);
063            writer.end("tr");
064            writer.println();
065        }
066    
067        private void trainForKeyValue(IMarkupWriter writer, String key, String value, boolean even)
068        {
069            writer.begin("tr");
070            writer.attribute("class", even ? "even" : "odd");
071            writer.begin("th");
072            if (key != null)
073                writer.print(key);
074            writer.end();
075            writer.begin("td");
076            writer.print(value);
077            writer.end("tr");
078            writer.println();
079        }
080    
081        private void trainForNestedKeyValue(IMarkupWriter writer, String key, String value, boolean even)
082        {
083            writer.begin("tr");
084            writer.attribute("class", even ? "even" : "odd");
085            writer.begin("th");
086            if (key != null)
087                writer.print(key);
088            writer.end();
089            writer.begin("td");
090            writer.print(value);
091            writer.println();
092            writer.end("tr");
093            writer.println();
094        }
095    
096        public void test_Set_Title_Twice_Fails()
097        {
098            IMarkupWriter writer = newWriter();
099            DescribableStrategy adapter = newStrategy();
100    
101            replay();
102    
103            DescriptionReceiver dr = new HTMLDescriptionReceiver(writer, adapter);
104    
105            dr.title("First Title");
106    
107            try
108            {
109                dr.title("Second Title");
110                unreachable();
111    
112            }
113            catch (IllegalStateException ex)
114            {
115                assertEquals(DescribeMessages.setTitleOnce(), ex.getMessage());
116            }
117    
118            verify();
119        }
120    
121        public void test_Set_Section_Before_Title_Fails()
122        {
123            IMarkupWriter writer = newWriter();
124            DescribableStrategy adapter = newStrategy();
125    
126            replay();
127    
128            DescriptionReceiver dr = new HTMLDescriptionReceiver(writer, adapter);
129    
130            try
131            {
132                dr.section("Section");
133                unreachable();
134            }
135            catch (IllegalStateException ex)
136            {
137                assertEquals(DescribeMessages.mustSetTitleBeforeSection(), ex.getMessage());
138            }
139    
140            verify();
141        }
142    
143        public void test_Int_Property()
144        {
145            IMarkupWriter writer = newWriter();
146            DescribableStrategy adapter = newStrategy();
147    
148            trainForTitle(writer, "Object Title");
149            trainForSection(writer, "Section");
150            trainForKeyValue(writer, "intProperty", "97", true);
151    
152            replay();
153    
154            DescriptionReceiver dr = new HTMLDescriptionReceiver(writer, adapter);
155    
156            dr.title("Object Title");
157            dr.section("Section");
158            dr.property("intProperty", 97);
159    
160            verify();
161        }
162    
163        public void test_Properties_Without_Section()
164        {
165            IMarkupWriter writer = newWriter();
166            DescribableStrategy adapter = newStrategy();
167    
168            trainForTitle(writer, "Object Title");
169            trainForKeyValue(writer, "first", "1", true);
170            trainForKeyValue(writer, "second", "2", false);
171    
172            replay();
173    
174            DescriptionReceiver dr = new HTMLDescriptionReceiver(writer, adapter);
175    
176            dr.title("Object Title");
177            dr.property("first", 1);
178            dr.property("second", 2);
179    
180            verify();
181    
182            trainForSection(writer, "Section 1");
183            trainForKeyValue(writer, "s1", "1", true);
184            trainForKeyValue(writer, "s2", "2", false);
185    
186            replay();
187    
188            dr.section("Section 1");
189            dr.property("s1", 1);
190            dr.property("s2", 2);
191    
192            verify();
193        }
194    
195        public void test_Finish_With_Properties()
196        {
197            IMarkupWriter writer = newWriter();
198            DescribableStrategy adapter = newStrategy();
199    
200            trainForTitle(writer, "Object Title");
201            trainForKeyValue(writer, "first", "1", true);
202    
203            replay();
204    
205            HTMLDescriptionReceiver dr = new HTMLDescriptionReceiver(writer, adapter);
206    
207            dr.title("Object Title");
208            dr.property("first", 1);
209    
210            verify();
211    
212            writer.end("table");
213            writer.println();
214    
215            replay();
216    
217            dr.finishUp(null);
218    
219            verify();
220        }
221    
222        public void test_Finish_No_Properties_No_Title()
223        {
224            IMarkupWriter writer = newWriter();
225            DescribableStrategy adapter = newStrategy();
226    
227            String object = "Fred";
228    
229            writer.print("Fred");
230            writer.println();
231    
232            replay();
233    
234            HTMLDescriptionReceiver dr = new HTMLDescriptionReceiver(writer, adapter);
235    
236            dr.finishUp(object);
237    
238            verify();
239        }
240    
241        public void test_Finish_No_Properties_With_Title()
242        {
243            IMarkupWriter writer = newWriter();
244            DescribableStrategy adapter = newStrategy();
245    
246            String object = "Fred";
247    
248            writer.print("Fred Title");
249            writer.println();
250    
251            replay();
252    
253            HTMLDescriptionReceiver dr = new HTMLDescriptionReceiver(writer, adapter);
254    
255            dr.title("Fred Title");
256    
257            dr.finishUp(object);
258    
259            verify();
260        }
261    
262        public void test_Array()
263        {
264            IMarkupWriter writer = newWriter();
265            DescribableStrategy adapter = new NoOpStrategy();
266    
267            Object[] array = new Object[]
268            { "Fred", "Barney" };
269    
270            trainForTitle(writer, "Array");
271            trainForNestedKeyValue(writer, "list", "Fred", true);
272            trainForNestedKeyValue(writer, null, "Barney", false);
273    
274            replay();
275    
276            HTMLDescriptionReceiver dr = new HTMLDescriptionReceiver(writer, adapter);
277    
278            dr.title("Array");
279            dr.array("list", array);
280    
281            verify();
282        }
283    
284        public void test_Collection()
285        {
286            IMarkupWriter writer = newWriter();
287            DescribableStrategy adapter = new NoOpStrategy();
288    
289            Object[] array = new Object[]
290            { "Fred", "Barney" };
291            Collection collection = Arrays.asList(array);
292    
293            trainForTitle(writer, "Collection");
294            trainForNestedKeyValue(writer, "list", "Fred", true);
295            trainForNestedKeyValue(writer, null, "Barney", false);
296    
297            replay();
298    
299            HTMLDescriptionReceiver dr = new HTMLDescriptionReceiver(writer, adapter);
300    
301            dr.title("Collection");
302            dr.collection("list", collection);
303    
304            verify();
305        }
306    
307        public void test_Array_Null_And_Empty()
308        {
309            IMarkupWriter writer = newWriter();
310            DescribableStrategy strategy = newStrategy();
311    
312            replay();
313    
314            HTMLDescriptionReceiver dr = new HTMLDescriptionReceiver(writer, strategy);
315    
316            dr.title("Array");
317            dr.array("null", null);
318            dr.array("empty", new Object[0]);
319    
320            verify();
321        }
322    
323        public void test_Collection_Null_And_Empty()
324        {
325            IMarkupWriter writer = newWriter();
326            DescribableStrategy strategy = newStrategy();
327    
328            replay();
329    
330            HTMLDescriptionReceiver dr = new HTMLDescriptionReceiver(writer, strategy);
331    
332            dr.title("Collection");
333            dr.collection("null", null);
334            dr.collection("empty", Collections.EMPTY_LIST);
335    
336            verify();
337        }
338    
339        public void test_Collection_Concurrent_Modification()
340        {
341            IMarkupWriter writer = newWriter();
342            DescribableStrategy adapter = new NoOpStrategy();
343            
344            final List list = new ArrayList();
345            list.add("Fred");
346            list.add("Barney");
347            
348            trainForTitle(writer, "Collection");
349            trainForNestedKeyValue(writer, "list", "Fred", true);
350            trainForNestedKeyValue(writer, null, "Barney", false);
351            
352            replay();
353            
354            HTMLDescriptionReceiver dr = new HTMLDescriptionReceiver(writer, adapter);
355            
356            dr.title("Collection");
357            dr.collection("list", list);
358            
359            verify();
360        }
361        
362        public void test_Scalar_Properties()
363        {
364            IMarkupWriter writer = newWriter();
365            DescribableStrategy strategy = newStrategy();
366    
367            trainForTitle(writer, "Scalars");
368            trainForKeyValue(writer, "boolean", "true", true);
369            trainForKeyValue(writer, "byte", "22", false);
370            trainForKeyValue(writer, "char", "*", true);
371            trainForKeyValue(writer, "short", "-8", false);
372            trainForKeyValue(writer, "int", "900", true);
373            trainForKeyValue(writer, "long", "200020", false);
374            trainForKeyValue(writer, "float", "3.14", true);
375            trainForKeyValue(writer, "double", "-2.7", false);
376    
377            replay();
378    
379            HTMLDescriptionReceiver dr = new HTMLDescriptionReceiver(writer, strategy);
380    
381            dr.title("Scalars");
382            dr.property("boolean", true);
383            dr.property("byte", (byte) 22);
384            dr.property("char", '*');
385            dr.property("short", (short) -8);
386            dr.property("int", 900);
387            dr.property("long", 200020l);
388            dr.property("float", (float) 3.14);
389            dr.property("double", -2.7);
390    
391            verify();
392        }
393    
394        public void test_Null_Root()
395        {
396            IMarkupWriter writer = newWriter();
397            DescribableStrategy strategy = newStrategy();
398    
399            writer.print(HTMLDescriptionReceiver.NULL_VALUE);
400    
401            replay();
402    
403            RootDescriptionReciever dr = new HTMLDescriptionReceiver(writer, strategy);
404    
405            dr.describe(null);
406    
407            verify();
408        }
409    
410        public void test_Null_Property()
411        {
412            IMarkupWriter writer = newWriter();
413            DescribableStrategy strategy = newStrategy();
414    
415            trainForTitle(writer, "Null Property");
416            trainForKeyValue(writer, "null", HTMLDescriptionReceiver.NULL_VALUE, true);
417    
418            replay();
419    
420            HTMLDescriptionReceiver dr = new HTMLDescriptionReceiver(writer, strategy);
421    
422            dr.title("Null Property");
423            dr.property("null", null);
424    
425            verify();
426    
427        }
428    
429        public void test_HTML_Describer()
430        {
431            IMarkupWriter writer = newWriter();
432            DescribableStrategy strategy = new NoOpStrategy();
433    
434            RootDescriptionReceiverFactory factory = newReceiverFactory();
435    
436            trainGetReciever(factory, writer, new HTMLDescriptionReceiver(writer, strategy));
437    
438            String object = "Tapestry";
439    
440            writer.print("Tapestry");
441            writer.println();
442    
443            replay();
444    
445            HTMLDescriberImpl d = new HTMLDescriberImpl();
446            d.setReceiverFactory(factory);
447    
448            d.describeObject(object, writer);
449    
450            verify();
451        }
452    
453        protected void trainGetReciever(RootDescriptionReceiverFactory factory, IMarkupWriter writer,
454                RootDescriptionReciever receiver)
455        {
456            expect(factory.newRootDescriptionReceiver(writer)).andReturn(receiver);
457        }
458    
459        protected RootDescriptionReceiverFactory newReceiverFactory()
460        {
461            return newMock(RootDescriptionReceiverFactory.class);
462        }
463        
464        public void test_Describe_Alternate()
465        {
466            IMarkupWriter writer = newWriter();
467            DescribableStrategy strategy = newStrategy();
468    
469            Object alternate = new Object();
470    
471            HTMLDescriptionReceiver dr = new HTMLDescriptionReceiver(writer, strategy);
472    
473            strategy.describeObject(alternate, dr);
474    
475            replay();
476    
477            dr.describeAlternate(alternate);
478    
479            verify();
480        }
481    }