KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > hp > hpl > jena > enhanced > test > TestPackage


1 /*
2   (c) Copyright 2003, 2004, 2005 Hewlett-Packard Development Company, LP
3   [See end of file]
4   $Id: TestPackage.java,v 1.14 2005/02/21 12:03:42 andy_seaborne Exp $
5 */

6 /*
7  * EnhancedTestSuite.java
8  *
9  * Created on 27 November 2002, 04:53
10  */

11
12 package com.hp.hpl.jena.enhanced.test;
13 import com.hp.hpl.jena.mem.*;
14 import com.hp.hpl.jena.graph.*;
15 import com.hp.hpl.jena.graph.test.*;
16 import com.hp.hpl.jena.enhanced.*;
17
18 import junit.framework.*;
19
20 /**
21  * These tests give a small version of a model-like interface
22  {@link TestModel} with different views
23  * over the nodes in the graph {@link TestSubject},
24  *{@link TestProperty} {@link TestObject}
25  *Any node can be any one of these three, but the interface only works
26  *if the node is the subject, property or object, respectively,
27   of some triple in the graph.
28  *There are two implementations of the three interfaces. We use four
29  * different
30  *personalities, in the tests, from various combinations of the implementation
31  *classes with the interface classes. A more realistic test would be a basic set
32  *of interfaces with implementations, and then some more extended interfaces and
33  *implementations which can work together.
34  *
35  *These tests only test EnhNode polymorphism and not EnhGraph polymorphism.
36  *EnhGraph polymorphism currently will not work.
37  *(For Jena2.0 I am imagining that there will be ModelCom and DAMLModelImpl as
38  *the only two implementations, and they can inherit one from the other).
39  * @author jjc
40  */

41 public class TestPackage extends GraphTestBase {
42     
43     static final private GraphPersonality split = new GraphPersonality();
44         
45     static final private GraphPersonality combo = new GraphPersonality();
46         
47         
48     static final private GraphPersonality bitOfBoth = new GraphPersonality();
49     static final private GraphPersonality broken = new GraphPersonality();
50     static {
51             // Setting up the personalities, involves registering how
52
// each interface is implemented by default.
53
// Note this does not guarantee that the only implementations
54
// of each interface will be the one specified.
55
// See bitOfBoth.
56
split.add( TestObject.class, TestObjectImpl.factory );
57         split.add( TestSubject.class, TestSubjectImpl.factory );
58         split.add( TestProperty.class, TestPropertyImpl.factory );
59         
60         combo.add( TestObject.class, TestAllImpl.factory );
61         combo.add( TestSubject.class, TestAllImpl.factory );
62         combo.add( TestProperty.class, TestAllImpl.factory );
63         
64         bitOfBoth.add( TestObject.class, TestObjectImpl.factory );
65         bitOfBoth.add( TestSubject.class, TestSubjectImpl.factory );
66         bitOfBoth.add( TestProperty.class, TestAllImpl.factory );
67         
68         // broken is misconfigured and must throw an exception.
69
broken.add(TestObject.class, TestObjectImpl.factory );
70         broken.add( TestSubject.class, TestSubjectImpl.factory );
71         broken.add( TestProperty.class, TestObjectImpl.factory );
72     }
73     /** Creates a new instance of EnhancedTestSuite */
74     public TestPackage(String JavaDoc name)
75         {
76         super( name );
77         }
78         
79     public static TestSuite suite()
80         { return new TestSuite( TestPackage.class ); }
81     
82     /**
83         test that equals works on an EnhNode (after hedgehog introduced FrontsNode
84         it didn't).
85     */

86     public void testEquals()
87         {
88         EnhNode a = new EnhNode( Node.create( "eg:example" ), null );
89         assertEquals( a, a );
90         }
91         
92     /**
93      * View n as intf. This is supported iff rslt.
94      */

95     private static void miniAsSupports(String JavaDoc title, TestNode n, Class JavaDoc intf, boolean rslt ) {
96         assertTrue(title +":sanity",n instanceof Polymorphic);
97         
98         // It is always possible to view any node with any interface.
99
TestNode as1 = (TestNode)((EnhNode)n).viewAs(intf);
100         TestNode as2 = (TestNode)((EnhNode)n).viewAs(intf);
101         
102         // caching should ensure we get the same result both times.
103
assertTrue( title + ":idempotency", as1==as2 );
104         
105         // Whether the interface is actually useable depends on the underlying
106
// graph. This factoid is the rslt parameter.
107
assertEquals( title +":support",rslt,((EnhNode) as1).supports( intf ) );
108     }
109     
110     private static void oneNodeAsSupports(String JavaDoc title, TestNode n, boolean rslts[] ) {
111         // Try n with all three interfaces.
112
miniAsSupports(title+"/TestSubject",n,TestSubject.class,rslts[0]);
113         miniAsSupports(title+"/TestProperty",n,TestProperty.class,rslts[1]);
114         miniAsSupports(title+"/TestObject",n,TestObject.class,rslts[2]);
115     }
116     
117     private static void manyNodeAsSupports(String JavaDoc title, TestNode n[], boolean rslts[][] ) {
118         // Try each n with each interface.
119
for (int i=0;i<n.length;i++){
120           oneNodeAsSupports(title+"["+i+"]",n[i],rslts[i]);
121         }
122     }
123     
124
125     /** This test show the basic format of an enhanced test.
126      * This test access data in an enhanced fashion.
127      * All modifications are done through the underlying graph.
128      * The methods tested are as and supports.
129      */

130     private static void basic(String JavaDoc title, Personality p) {
131         Graph g = new GraphMem();
132         TestModel model = new TestModelImpl(g,p);
133         // create some data
134
graphAdd( g, "x R y;" );
135         
136         // The graph has three nodes, extract them as TestNode's,
137
// using the minimalist ModelAPI.
138
TestNode nodes[] = new TestNode[]{
139             model.aSubject(),
140             model.aProperty(),
141             model.anObject()
142         };
143         
144         // Run the basic tests.
145
manyNodeAsSupports(title+"(a)",nodes,
146            new boolean[][]{
147                new boolean[]{true,false,false}, // nodes[0] is subj, but not prop, or obj
148
new boolean[]{false,true,false},
149                new boolean[]{false,false,true}
150         });
151         
152         graphAdd(g,"y R x;" );
153         
154         // The expected results are now different.
155
// (A node is appropriate for the TestSubject interface if it is
156
// the subject of some triple in the graph, so the third node
157
// can now be a TestSubject).
158
manyNodeAsSupports(title+"(b)",nodes,
159            new boolean[][]{
160                new boolean[]{true,false,true}, // nodes[0] is subj and obj, but not prop
161
new boolean[]{false,true,false},
162                new boolean[]{true,false,true}
163         });
164         
165         g.delete( triple( "x R y" ) );
166
167         // The expected results are now different again.
168
// (A node is appropriate for the TestSubject interface if it is
169
// the subject of some triple in the graph, so the third node
170
// can now be a TestSubject).
171

172         manyNodeAsSupports(title+"(c)",nodes,
173            new boolean[][]{
174                new boolean[]{false,false,true},
175                new boolean[]{false,true,false},
176                new boolean[]{true,false,false}
177         });
178         
179         
180     }
181
182     /**
183         Would like to get rid of these, but the abstraction is hard to find at the
184         moment. At least they're now just local to this test class.
185     */

186     static final int S = 1;
187     static final int P = 2;
188     static final int O = 3;
189     
190     // This is like the earlier test: miniAsSupports (the last part of it).
191
// However, this time instead of asking whether the interface will work
192
// or not, we just try it.
193
// Obviously sometimes it is broken, which should be reported using
194
// an IllegalStateException.
195
private void canImplement(String JavaDoc title, TestNode n, int wh, boolean rslt ) {
196         try {
197             switch (wh) {
198                 case S:
199                     n.asSubject().aProperty();
200                     break;
201                 case P:
202                     n.asProperty().anObject();
203                     break;
204                 case O:
205                     n.asObject().aSubject();
206                     break;
207             }
208             assertTrue("IllegalStateException expected.",rslt);
209         }
210         catch (IllegalStateException JavaDoc e) {
211             assertFalse("IllegalStateException at the wrong time.",rslt);
212         }
213     }
214
215     private void canImplement(String JavaDoc title, TestNode n, boolean rslts[] ) {
216         canImplement(title+"/TestSubject",n,S,rslts[0]);
217         canImplement(title+"/TestProperty",n,P,rslts[1]);
218         canImplement(title+"/TestObject",n,O,rslts[2]);
219     }
220     private void canImplement(String JavaDoc title, TestNode n[], boolean rslts[][] ) {
221         for (int i=0;i<n.length;i++){
222           canImplement(title+"["+i+"]",n[i],rslts[i]);
223         }
224     }
225     
226     private void follow(String JavaDoc title, Personality p) {
227         Graph g = new GraphMem();
228         TestModel model = new TestModelImpl(g,p);
229         // create some data
230
graphAdd( g, "a b c;" );
231         TestNode nodes[] = new TestNode[]{
232             model.aSubject(),
233             model.aProperty(),
234             model.anObject()
235         };
236         
237         // Similar to the basic test.
238
canImplement(title+"(a)",nodes,
239            new boolean[][]{
240                new boolean[]{true,false,false},
241                new boolean[]{false,true,false},
242                new boolean[]{false,false,true}
243         });
244         
245         graphAdd(g, "b a c;" );
246
247         // Again like in the basic test the triples have now changed,
248
// so different methods will now work.
249
canImplement(title+"(b)",nodes,
250            new boolean[][]{
251                new boolean[]{true,true,false},
252                new boolean[]{true,true,false},
253                new boolean[]{false,false,true}
254         });
255         
256         g.delete(triple( "a b c" ) );
257
258
259         // Again like in the basic test the triples have now changed,
260
// so different methods will now work.
261
canImplement(title+"(c)",nodes,
262            new boolean[][]{
263                new boolean[]{false,true,false},
264                new boolean[]{true,false,false},
265                new boolean[]{false,false,true}
266         });
267
268         // Another twist.
269
canImplement(title+"(c)",new TestNode[]{
270             nodes[1].asSubject().aProperty(),
271             nodes[2].asObject().aSubject(),
272             nodes[0].asProperty().anObject()
273         },
274            new boolean[][]{
275                new boolean[]{false,true,false},
276                new boolean[]{true,false,false},
277                new boolean[]{false,false,true}
278         });
279         assertTrue("Model cache test",nodes[0].asProperty().anObject()==nodes[2]);
280     }
281     private void cache(String JavaDoc title, Personality p) {
282         Graph g = new GraphMem();
283         TestModel model = new TestModelImpl(g,p);
284         // create some data
285
graphAdd( g, "a b a;" );
286         
287         // get the same node in two different ways.
288
assertTrue("Caching is on",model.aSubject().asObject()==model.anObject());
289         
290         ((TestModelImpl)model).getNodeCacheControl().setEnabled(false);
291         
292
293         // get the same node in two different ways; if there isn't any caching
294
// then we reconstruct the node.
295
assertFalse("Caching is off",model.aSubject()==model.anObject());
296         
297     }
298     public static void testSplitBasic() {
299        basic("Split: ",split);
300     }
301     public static void testComboBasic() {
302      basic("Combo: ",combo);
303     }
304     public void testSplitFollow() {
305        follow("Split: ",split);
306     }
307     public void testComboFollow() {
308      follow("Combo: ",combo);
309     }
310     
311     public void testSplitCache() {
312         cache("Split: ",split);
313     }
314     public void testComboCache() {
315      cache("Combo: ",combo);
316     }
317     
318     public static void testBitOfBothBasic() {
319        basic("bob: ",bitOfBoth);
320     }
321     public void testBitOfBothFollow() {
322        follow("bob: ",bitOfBoth);
323     }
324     
325     public void testBitOfBothCache() {
326         cache("bob: ",bitOfBoth);
327     }
328     
329     public static void testBitOfBothSurprise() {
330         // bitOfBoth is a surprising personality ...
331
// we can have two different java objects implementing the same interface.
332

333         Graph g = new GraphMem();
334         TestModel model = new TestModelImpl(g,bitOfBoth);
335         // create some data
336
graphAdd( g, "a a a;" );
337         TestSubject testSubjectImpl = model.aSubject();
338         assertTrue("BitOfBoth makes subjects using TestSubjectImpl",
339                  testSubjectImpl instanceof TestSubjectImpl);
340         TestProperty testAllImpl = testSubjectImpl.aProperty();
341         assertTrue("BitOfBoth makes properties using TestAllImpl",
342                  testAllImpl instanceof TestAllImpl);
343         assertTrue("turning a TestAllImpl into a TestSubject is a no-op",
344                   testAllImpl == testAllImpl.asSubject() );
345         assertTrue("turning a TestAllImpl into a TestSubject is a no-op",
346                   testSubjectImpl != testAllImpl.asSubject() );
347         assertTrue("turning a TestAllImpl into a TestSubject is a no-op",
348                   testSubjectImpl.asSubject() != testSubjectImpl.asSubject().asProperty().asSubject() );
349                   
350     }
351     
352     public static void testBrokenBasic() {
353         try {
354             // Any of the tests ought to work up and til the point
355
// that they don't. At that point they need to detect the
356
// error and throw the PersonalityConfigException.
357
basic("Broken: ",broken);
358            fail("broken is a misconfigured personality, but it wasn't detected.");
359         }
360         catch (PersonalityConfigException e ) {
361             
362         }
363     }
364     
365     static class Example
366         {
367         static final Implementation factory = new Implementation()
368             {
369             public EnhNode wrap( Node n, EnhGraph g ) { return new EnhNode( n, g ); }
370             
371             public boolean canWrap( Node n, EnhGraph g ) { return n.isURI(); }
372             };
373         }
374     
375     public void testSimple()
376         {
377         Graph g = new GraphMem();
378         Personality ours = BuiltinPersonalities.model.copy().add( Example.class, Example.factory );
379         EnhGraph eg = new EnhGraph( g, ours );
380         Node n = Node.createURI( "spoo:bar" );
381         EnhNode eNode = new EnhNode( Node.createURI( "spoo:bar" ), eg );
382         EnhNode eBlank = new EnhNode( Node.createAnon(), eg );
383         assertTrue( "URI node can be an Example", eNode.supports( Example.class ) );
384         assertFalse( "Blank node cannot be an Example", eBlank.supports( Example.class ) );
385         }
386         
387     static class AnotherExample
388         {
389         static final Implementation factory = new Implementation()
390             {
391             public EnhNode wrap( Node n, EnhGraph g ) { return new EnhNode( n, g ); }
392             
393             public boolean canWrap( Node n, EnhGraph g ) { return n.isURI(); }
394             };
395         }
396     
397     public void testAlreadyLinkedViewException()
398         {
399          Graph g = new GraphMem();
400          Personality ours = BuiltinPersonalities.model.copy().add( Example.class, Example.factory );
401          EnhGraph eg = new EnhGraph( g, ours );
402          Node n = Node.create( "spoo:bar" );
403          EnhNode eNode = new EnhNode( n, eg );
404          eNode.viewAs( Example.class );
405          try
406             {
407             eNode.addView( eNode );
408             fail( "should raise an AlreadyLinkedViewException " );
409             }
410         catch (AlreadyLinkedViewException e)
411             {}
412         }
413         
414     /**
415         Test that an attempt to polymorph an enhanced node into a class that isn't
416         supported by the enhanced graph generates an UnsupportedPolymorphism
417         exception.
418     */

419     public void testNullPointerTrap()
420         {
421         EnhGraph eg = new EnhGraph( new GraphMem(), BuiltinPersonalities.model );
422         Node n = Node.create( "eh:something" );
423         EnhNode en = new EnhNode( n, eg );
424         try
425             {
426             en.as( TestPackage.class );
427             fail( "oops" );
428             }
429         catch (UnsupportedPolymorphismException e)
430             {
431             assertTrue( "exception should have cuplprit graph", eg == e.getBadGraph() );
432             assertTrue( "exception should have culprit class", TestPackage.class == e.getBadClass() );
433             }
434         }
435
436 }
437
438 /*
439     (c) Copyright 2003, 2004, 2005 Hewlett-Packard Development Company, LP
440     All rights reserved.
441
442     Redistribution and use in source and binary forms, with or without
443     modification, are permitted provided that the following conditions
444     are met:
445
446     1. Redistributions of source code must retain the above copyright
447        notice, this list of conditions and the following disclaimer.
448
449     2. Redistributions in binary form must reproduce the above copyright
450        notice, this list of conditions and the following disclaimer in the
451        documentation and/or other materials provided with the distribution.
452
453     3. The name of the author may not be used to endorse or promote products
454        derived from this software without specific prior written permission.
455
456     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
457     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
458     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
459     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
460     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
461     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
462     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
463     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
464     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
465     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
466 */

467
Popular Tags