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.components;
016    
017    import static org.easymock.EasyMock.expect;
018    
019    import java.text.DateFormat;
020    import java.text.Format;
021    import java.util.Date;
022    
023    import org.apache.hivemind.ApplicationRuntimeException;
024    import org.apache.hivemind.Location;
025    import org.apache.tapestry.BaseComponentTestCase;
026    import org.apache.tapestry.IBinding;
027    import org.apache.tapestry.IMarkupWriter;
028    import org.apache.tapestry.IPage;
029    import org.apache.tapestry.IRequestCycle;
030    import org.apache.tapestry.html.BasePage;
031    import org.apache.tapestry.spec.IComponentSpecification;
032    import org.testng.annotations.Test;
033    
034    /**
035     * Tests for the {@link org.apache.tapestry.components.Insert}  component.
036     * 
037     * @author Howard M. Lewis Ship
038     * @since 4.0
039     */
040    @Test
041    public class TestInsert extends BaseComponentTestCase
042    {
043        /**
044         * Returns a new page instance (not a mock page).
045         */
046    
047        private IPage newBasePage(String name)
048        {
049            BasePage page = (BasePage) newInstance(BasePage.class);
050    
051            page.setPageName(name);
052    
053            return page;
054        }
055    
056        public void test_Rewinding()
057        {
058            IRequestCycle cycle = newCycle(true);
059            
060            Insert insert = (Insert) newInstance(Insert.class);
061            
062            expect(cycle.renderStackPush(insert)).andReturn(insert);
063            
064            expect(cycle.renderStackPop()).andReturn(insert);
065            
066            replay();
067    
068            insert.render(null, cycle);
069    
070            verify();
071        }
072    
073        public void test_Null_Value()
074        {
075            IRequestCycle cycle = newCycle(false);
076            
077            Insert insert = newInstance(Insert.class, 
078                    new Object[] { "value", null });
079            
080            expect(cycle.renderStackPush(insert)).andReturn(insert);
081            
082            expect(cycle.renderStackPop()).andReturn(insert);
083            
084            replay();
085            
086            insert.render(null, cycle);
087    
088            verify();
089        }
090    
091        public void test_No_Format()
092        {
093            IMarkupWriter writer = newWriter();
094            IRequestCycle cycle = newCycle(false);
095            
096            Insert insert = newInstance(Insert.class, 
097                    new Object[] { "value", new Integer(42) });
098            
099            expect(cycle.renderStackPush(insert)).andReturn(insert);
100            
101            writer.print("42", false);
102            
103            expect(cycle.renderStackPop()).andReturn(insert);
104            
105            replay();
106            
107            insert.render(writer, cycle);
108    
109            verify();
110        }
111    
112        public void test_Format()
113        {
114            IMarkupWriter writer = newWriter();
115            IRequestCycle cycle = newCycle(false);
116            
117            Date date = new Date();
118            DateFormat format = DateFormat.getDateInstance();
119            String expected = format.format(date);
120            
121            Insert insert = newInstance(Insert.class, 
122                    new Object[]{ "value", date, "format", format });
123            
124            expect(cycle.renderStackPush(insert)).andReturn(insert);
125            
126            writer.print(expected, false);
127            
128            expect(cycle.renderStackPop()).andReturn(insert);
129            
130            replay();
131    
132            insert.render(writer, cycle);
133    
134            verify();
135        }
136    
137        public void test_Unable_To_Format()
138        {
139            Object value = "xyzzyx";
140            Location l = fabricateLocation(87);
141            IBinding binding = newBinding(l);
142            
143            Format format = DateFormat.getInstance();
144            
145            Insert insert = newInstance(Insert.class, 
146                    new Object[] { "value", value, "format", format });
147            
148            IRequestCycle cycle = newCycle(false);
149            IMarkupWriter writer = newWriter();
150            
151            IPage page = newBasePage("Flintstone");
152            
153            expect(cycle.renderStackPush(insert)).andReturn(insert);
154            
155            expect(cycle.renderStackPop()).andReturn(insert);
156            
157            replay();
158            
159            insert.setBinding("format", binding);
160            insert.setId("fred");
161            insert.setPage(page);
162            insert.setContainer(page);
163    
164            try
165            {
166                insert.render(writer, cycle);
167                unreachable();
168            }
169            catch (ApplicationRuntimeException ex)
170            {
171                assertEquals(
172                        "Flintstone/fred unable to format value 'xyzzyx': Cannot format given Object as a Date",
173                        ex.getMessage());
174                assertSame(insert, ex.getComponent());
175                assertSame(l, ex.getLocation());
176            }
177    
178            verify();
179        }
180    
181        public void test_Raw()
182        {
183            IRequestCycle cycle = newCycle(false);
184            IMarkupWriter writer = newWriter();
185            
186            Insert insert = newInstance(Insert.class, 
187                    new Object[] { "value", new Integer(42), "raw", Boolean.TRUE });
188            
189            expect(cycle.renderStackPush(insert)).andReturn(insert);
190            
191            writer.print("42", true);
192            
193            expect(cycle.renderStackPop()).andReturn(insert);
194            
195            replay();
196    
197            insert.render(writer, cycle);
198    
199            verify();
200        }
201    
202        public void test_Style_Class()
203        {
204            IBinding informal = newBinding("informal-value");
205            IBinding classBinding = newBinding("paisley");
206            
207            IRequestCycle cycle = newCycle(false, false);
208            IMarkupWriter writer = newWriter();
209            
210            IComponentSpecification spec = newSpec("informal", null);
211            
212            Insert insert = newInstance(Insert.class, 
213                    new Object[] { 
214                "value", "42", 
215                "specification", spec,
216                "templateTagName", "span"
217            });
218            
219            expect(cycle.renderStackPush(insert)).andReturn(insert);
220            
221            writer.begin("span");
222            
223            expect(spec.getParameter("class")).andReturn(null);
224            
225            writer.attribute("class", "paisley");
226            writer.attribute("informal", "informal-value");
227            
228            writer.print("42", false);
229            writer.end();
230            
231            expect(cycle.renderStackPop()).andReturn(insert);
232            
233            replay();
234            
235            insert.setBinding("class", classBinding);
236            insert.setBinding("informal", informal);
237    
238            insert.render(writer, cycle);
239    
240            verify();
241        }
242        
243        public void test_Render_Breaks()
244        {
245            IMarkupWriter writer = newWriter();
246            IRequestCycle cycle = newCycle(false);
247            
248            Insert component = newInstance(Insert.class,
249                    new Object[] {
250                "value",
251            "Now is the time\nfor all good men\nto come to the aid of their Tapestry.",
252                "mode", InsertMode.BREAK
253                }
254            );
255            
256            expect(cycle.renderStackPush(component)).andReturn(component);
257            
258            writer.print("Now is the time", false);
259            writer.beginEmpty("br");
260            writer.print("for all good men", false);
261            writer.beginEmpty("br");
262            writer.print("to come to the aid of their Tapestry.", false);
263            
264            expect(cycle.renderStackPop()).andReturn(component);
265            
266            replay();
267            
268            component.render(writer, cycle);
269    
270            verify();
271        }
272    
273        public void test_Render_Paras()
274        {
275            IMarkupWriter writer = newWriter();
276            IRequestCycle cycle = newCycle(false);
277    
278            Insert component = newInstance(Insert.class, 
279                    new Object[] { "mode", InsertMode.PARAGRAPH, "value",
280            "Now is the time\nfor all good men\nto come to the aid of their Tapestry." });
281            
282            expect(cycle.renderStackPush(component)).andReturn(component);
283            
284            writer.begin("p");
285            writer.print("Now is the time", false);
286            writer.end();
287    
288            writer.begin("p");
289            writer.print("for all good men", false);
290            writer.end();
291    
292            writer.begin("p");
293            writer.print("to come to the aid of their Tapestry.", false);
294            writer.end();
295            
296            expect(cycle.renderStackPop()).andReturn(component);
297            
298            replay();
299            
300            component.render(writer, cycle);
301    
302            verify();
303        }
304        
305        public void test_Render_Raw()
306        {
307            IMarkupWriter writer = newWriter();
308            IRequestCycle cycle = newCycle(false);
309    
310            Insert component = newInstance(Insert.class, 
311                    new Object[] { "value", "output\n<b>raw</b>", 
312                "raw", Boolean.TRUE, "mode", InsertMode.BREAK });
313            
314            expect(cycle.renderStackPush(component)).andReturn(component);
315            
316            writer.print("output", true);
317            writer.beginEmpty("br");
318            writer.print("<b>raw</b>", true);
319            
320            expect(cycle.renderStackPop()).andReturn(component);
321            
322            replay();
323    
324            component.finishLoad(cycle, null, null);
325            component.render(writer, cycle);
326    
327            verify();
328        }
329        
330        public void test_Render_Nested_Raw()
331        {
332            IMarkupWriter writer = newBufferWriter();
333            IRequestCycle cycle = newCycle(false);
334            
335            Insert component = newInstance(Insert.class, 
336                    new Object[] { "value", "output\n<b>raw</b>", 
337                "raw", Boolean.TRUE, "mode", InsertMode.BREAK });
338            
339            expect(cycle.renderStackPush(component)).andReturn(component);
340            
341            IMarkupWriter nested = writer.getNestedWriter();
342            
343            expect(cycle.renderStackPop()).andReturn(component);
344            
345            replay();
346    
347            component.finishLoad(cycle, null, null);
348            component.render(nested, cycle);
349            
350            verify();
351            
352            nested.close();
353            
354            assertBuffer("output<br /><b>raw</b>");
355        }
356    }