- Revision
- 595
- Author
- sirenian
- Date
- 2006-11-30 05:53:58 -0600 (Thu, 30 Nov 2006)
Log Message
[EK] Build is fixed (and classes can still mostly be mocked, thanks to ProxyToys!) but some hellbound swing stuff still failing in 1.4.
Modified Paths
- trunk/build.xml
- trunk/examples/hellbound/src/behaviour/com/sirenian/hellbound/domain/glyph/LivingGlyphBehaviour.java
- trunk/examples/hellbound/src/behaviour/com/sirenian/hellbound/domain/glyph/VerifiableGlyphListener.java
- trunk/examples/hellbound/src/behaviour/com/sirenian/hellbound/engine/GameBehaviour.java
- trunk/examples/hellbound/src/java/com/sirenian/hellbound/domain/glyph/LivingGlyph.java
- trunk/examples/hellbound/src/java/com/sirenian/hellbound/engine/Game.java
- trunk/extensions/classmocks/src/behaviour/jbehave/extensions/classmock/ClassMockObjectBehaviour.java
- trunk/extensions/classmocks/src/behaviour/jbehave/extensions/classmock/UsingClassMockBehaviour.java
- trunk/extensions/classmocks/src/java/jbehave/extensions/classmock/ClassMockObject.java
- trunk/extensions/classmocks/src/java/jbehave/extensions/classmock/UsingClassMock.java
Added Paths
Diff
Modified: trunk/build.xml (594 => 595)
--- trunk/build.xml 2006-11-30 07:26:29 UTC (rev 594) +++ trunk/build.xml 2006-11-30 11:53:58 UTC (rev 595) @@ -19,6 +19,7 @@ <fileset dir="${lib_dir}" includes="extensions/fit-1.1.jar" /> <fileset dir="${lib_dir}" includes="extensions/cotta-1.0.jar" /> <fileset dir="${lib_dir}" includes="extensions/velocity-dep-1.4.jar" /> + <fileset dir="${lib_dir}" includes="extensions/proxytoys-0.2.1.jar" /> </path> <!-- build output structure --> @@ -97,7 +98,7 @@ <target name="compile-behaviour" depends="build-jar" description="Compile behaviour"> <mkdir dir="${behaviour_classes_dir}" /> - <javac taskname="compile behaviours" destdir="${behaviour_classes_dir}" source="1.4" target="1.4" debug="true"> + <javac taskname="compile behaviours" destdir="${behaviour_classes_dir}" source="${jdk.version}" target="${jdk.version}" debug="true"> <src> <pathelement path="${core_dir}/src/behaviour" /> <pathelement path="${everything_dir}/src/behaviour" />
Modified: trunk/examples/hellbound/src/behaviour/com/sirenian/hellbound/domain/glyph/LivingGlyphBehaviour.java (594 => 595)
--- trunk/examples/hellbound/src/behaviour/com/sirenian/hellbound/domain/glyph/LivingGlyphBehaviour.java 2006-11-30 07:26:29 UTC (rev 594) +++ trunk/examples/hellbound/src/behaviour/com/sirenian/hellbound/domain/glyph/LivingGlyphBehaviour.java 2006-11-30 11:53:58 UTC (rev 595) @@ -59,12 +59,40 @@ Segments firstSegments = listener.toLastSegments(); ensureThat(!glyph.requestMoveDown()); + ensureThat(!glyph.requestMoveRight()); + ensureThat(!glyph.requestMoveLeft()); Segments secondSegments = listener.toLastSegments(); ensureThat(firstSegments, eq(secondSegments)); } + public void shouldMoveIfNotInCollision() { + CollisionDetector detector = new CollisionDetector() { + public boolean collides(Segments segments) { + return false; + } + }; + + glyph = new LivingGlyph( + GlyphType.O, + detector, + 4); + + Segments latestSegments = glyph.getSegments(); + + ensureThat(glyph.requestMoveDown()); + ensureThat(glyph.getSegments(), eq(latestSegments.movedDown())); + latestSegments = latestSegments.movedDown(); + + ensureThat(glyph.requestMoveRight()); + ensureThat(glyph.getSegments(), eq(latestSegments.movedRight())); + latestSegments = latestSegments.movedRight(); + + ensureThat(glyph.requestMoveLeft()); + ensureThat(glyph.getSegments(), eq(latestSegments.movedLeft())); + } + public void shouldReduceSegmentsToEmptyIfKilled() { setUp(); Segments originalSegments = glyph.getSegments();
Modified: trunk/examples/hellbound/src/behaviour/com/sirenian/hellbound/domain/glyph/VerifiableGlyphListener.java (594 => 595)
--- trunk/examples/hellbound/src/behaviour/com/sirenian/hellbound/domain/glyph/VerifiableGlyphListener.java 2006-11-30 07:26:29 UTC (rev 594) +++ trunk/examples/hellbound/src/behaviour/com/sirenian/hellbound/domain/glyph/VerifiableGlyphListener.java 2006-11-30 11:53:58 UTC (rev 595) @@ -9,7 +9,6 @@ private Segments fromSegments; public void reportGlyphMovement(GlyphType type, Segments fromSegments, Segments toSegments) { - Logger.debug(this, "Glyph movement reported from " + fromSegments + " to " + toSegments + " with type " + type); this.fromSegments = fromSegments; this.toSegments = toSegments; this.type = type;
Modified: trunk/examples/hellbound/src/behaviour/com/sirenian/hellbound/engine/GameBehaviour.java (594 => 595)
--- trunk/examples/hellbound/src/behaviour/com/sirenian/hellbound/engine/GameBehaviour.java 2006-11-30 07:26:29 UTC (rev 594) +++ trunk/examples/hellbound/src/behaviour/com/sirenian/hellbound/engine/GameBehaviour.java 2006-11-30 11:53:58 UTC (rev 595) @@ -86,24 +86,22 @@ verifyMocks(); } - public void shouldDelegateMovementRequestsToGlyph() { - Mock glyphFactory = mock(GlyphFactory.class); - Mock glyph = mock(LivingGlyph.class, new Class[]{GlyphType.class, CollisionDetector.class, int.class}, - new Object[] {GlyphType.NULL, CollisionDetector.NULL, Integer.valueOf(3)}); - glyphFactory.stubs("nextGlyph").will(returnValue(glyph)); + public void shouldMoveGlyphWhenRequested() { + AccessibleFactory factory = new AccessibleFactory(); + Game game = new Game(factory, new StubHeartbeat(), 7, 13); + Segments latestSegments = GlyphType.T.getSegments(0).movedRight(3); + game.requestStartGame(); - Game game = new Game((GlyphFactory) glyphFactory, new StubHeartbeat(), 7, 13); + game.requestMoveGlyphDown(); + ensureThat(factory.glyph.getSegments(), eq(latestSegments.movedDown())); + latestSegments = latestSegments.movedDown(); - glyph.expects("requestMoveDown").will(returnValue(true)); - glyph.expects("requestMoveLeft").will(returnValue(true)); - glyph.expects("requestMoveRight").will(returnValue(true)); - glyph.expects("drop"); + game.requestMoveGlyphLeft(); + ensureThat(factory.glyph.getSegments(), eq(latestSegments.movedLeft())); + latestSegments = latestSegments.movedLeft(); - game.requestStartGame(); - game.requestMoveGlyphDown(); - game.requestMoveGlyphLeft(); game.requestMoveGlyphRight(); - game.requestDropGlyph(); + ensureThat(factory.glyph.getSegments(), eq(latestSegments.movedRight())); verifyMocks(); } @@ -145,4 +143,16 @@ } return result; } + + private static class AccessibleFactory extends PseudoRandomGlyphFactory { + private AccessibleFactory() { + super(42); + } + + LivingGlyph glyph; + public LivingGlyph nextGlyph(int center, CollisionDetector detector, ListenerSet glyphListeners) { + glyph = super.nextGlyph(center, detector, glyphListeners); + return glyph; + } + } }
Modified: trunk/examples/hellbound/src/java/com/sirenian/hellbound/domain/glyph/LivingGlyph.java (594 => 595)
--- trunk/examples/hellbound/src/java/com/sirenian/hellbound/domain/glyph/LivingGlyph.java 2006-11-30 07:26:29 UTC (rev 594) +++ trunk/examples/hellbound/src/java/com/sirenian/hellbound/domain/glyph/LivingGlyph.java 2006-11-30 11:53:58 UTC (rev 595) @@ -25,15 +25,27 @@ } public boolean requestMoveDown() { - Segments newSegments = segments.movedDown(); - if (detector.collides(newSegments)) { - return false; - } else { - moveTo(newSegments); - return true; - } + return attemptMoveTo(segments.movedDown()); } + public boolean requestMoveLeft() { + return attemptMoveTo(segments.movedLeft()); + } + + + public boolean requestMoveRight() { + return attemptMoveTo(segments.movedRight()); + } + + private boolean attemptMoveTo(Segments newSegments) { + if (detector.collides(newSegments)) { + return false; + } else { + moveTo(newSegments); + return true; + } + } + public void drop() { Segments segmentsToMoveTo = segments; Segments nextSegmentsDown = segments.movedDown(); @@ -51,4 +63,6 @@ public String toString() { return "LivingGlyph[ " + type + ", " + segments + "]"; } + + }
Modified: trunk/examples/hellbound/src/java/com/sirenian/hellbound/engine/Game.java (594 => 595)
--- trunk/examples/hellbound/src/java/com/sirenian/hellbound/engine/Game.java 2006-11-30 07:26:29 UTC (rev 594) +++ trunk/examples/hellbound/src/java/com/sirenian/hellbound/engine/Game.java 2006-11-30 11:53:58 UTC (rev 595) @@ -103,23 +103,26 @@ private void moveGlyphDownOrJunkIt() { if (!glyph.requestMoveDown()) { + Logger.debug(this, "Could not move glyph down; junking it"); junk.absorb(glyph); resetGlyph(); } } public void requestMoveGlyphDown() { + Logger.debug(this, "Move down glyph requested"); moveGlyphDownOrJunkIt(); } public void requestMoveGlyphLeft() { - // TODO Auto-generated method stub + Logger.debug(this, "Move left glyph requested"); + glyph.requestMoveLeft(); } public void requestMoveGlyphRight() { - // TODO Auto-generated method stub - + Logger.debug(this, "Move right glyph requested"); + glyph.requestMoveRight(); }
Modified: trunk/extensions/classmocks/src/behaviour/jbehave/extensions/classmock/ClassMockObjectBehaviour.java (594 => 595)
--- trunk/extensions/classmocks/src/behaviour/jbehave/extensions/classmock/ClassMockObjectBehaviour.java 2006-11-30 07:26:29 UTC (rev 594) +++ trunk/extensions/classmocks/src/behaviour/jbehave/extensions/classmock/ClassMockObjectBehaviour.java 2006-11-30 11:53:58 UTC (rev 595) @@ -2,7 +2,6 @@ import java.util.HashMap; -import jbehave.core.Block; import jbehave.core.Ensure; import jbehave.core.exception.PendingException; import jbehave.core.minimock.UsingMiniMock; @@ -19,7 +18,7 @@ } } - private static class AClassWithNoDeclaredConstructors {} + public static class AClassWithNoDeclaredConstructors {} public static class AClassWithAComplexConstructor { @@ -34,19 +33,6 @@ } } - public static class AClassWithAReallyNastyConstructor { - public AClassWithAReallyNastyConstructor( - String anObject, - int primitive, - char primitive2, - Object[] array, - AClassWithNoConstructorsAtAll someEnum) { - anObject.compareTo(someEnum.toString()); - int i = primitive + array.length; - i++; // just to stop the unused warnings - } - } - public static class AClassWithNoConstructorsAtAll { public static final Object INSTANCE = new AClassWithNoConstructorsAtAll(); private AClassWithNoConstructorsAtAll() {} @@ -61,22 +47,6 @@ ClassMockObject.mockClass(AClassWithConstructorArgs.class, "bar"); } - public void shouldThrowAnIllegalArgumentExceptionIfClassIsStaticInnerClass() throws Exception { - Ensure.throwsException(IllegalArgumentException.class, new Block() { - public void run() throws Exception { - ClassMockObject.mockClass(ANonStaticInnerClass.class, "bar"); - } - }); - } - - public void shouldThrowAnIllegalArgumentExceptionIfClassHasNoConstructors() throws Exception { - Ensure.throwsException(IllegalArgumentException.class, new Block() { - public void run() throws Exception { - ClassMockObject.mockClass(AClassWithNoDeclaredConstructors.class, "bar"); - } - }); - } - public void shouldBeAbleToUseMockedClassesJustLikeOtherMocks() { Object expected = new Object(); Mock mock = ClassMockObject.mockClass(HashMap.class, "hashMap"); @@ -85,36 +55,15 @@ Object actual = ((HashMap)mock).get("a key"); ensureThat(expected, eq(actual)); } - - public void shouldBeAbleToProvideDefaultInstancesForConstructorClasses() { - Mock mock = ClassMockObject.mockClass( - AClassWithAReallyNastyConstructor.class, "foo", - new Class[] { - String.class, - int.class, - char.class, - Object[].class, - AClassWithNoConstructorsAtAll.class}, - new Object[] { - "", - new Integer(0), - new Character(' '), - new Object[0], - AClassWithNoConstructorsAtAll.INSTANCE}); + + public void shouldBeAbleToMockClassesWithUndeclaredConstructors() { + ClassMockObject.mockClass(AClassWithNoDeclaredConstructors.class, "foo"); } - + public void shouldBeAbleToMockMostClassesWithConstructorArgs() { ClassMockObject.mockClass(AClassWithAComplexConstructor.class, "foo"); } - public void shouldRethrowNullPointerExceptionsWithSuggestionWhenConstructorFails() throws Exception { - ensureThrows(IllegalArgumentException.class, new Block() { - public void run() throws Exception { - ClassMockObject.mockClass(AClassWithAReallyNastyConstructor.class, "foo"); - } - }); - } - public void shouldBeAbleToProvideMinimalProblemClassConstructorsAndHaveTheFactoryFillInTheRest() { throw new PendingException(); }
Modified: trunk/extensions/classmocks/src/behaviour/jbehave/extensions/classmock/UsingClassMockBehaviour.java (594 => 595)
--- trunk/extensions/classmocks/src/behaviour/jbehave/extensions/classmock/UsingClassMockBehaviour.java 2006-11-30 07:26:29 UTC (rev 594) +++ trunk/extensions/classmocks/src/behaviour/jbehave/extensions/classmock/UsingClassMockBehaviour.java 2006-11-30 11:53:58 UTC (rev 595) @@ -5,8 +5,6 @@ import jbehave.core.exception.PendingException; import jbehave.core.minimock.UsingMiniMock; import jbehave.core.mock.Mock; -import jbehave.extensions.classmock.UsingClassMock; -import jbehave.extensions.classmock.ClassMockObjectBehaviour.AClassWithAReallyNastyConstructor; import jbehave.extensions.classmock.ClassMockObjectBehaviour.AClassWithNoConstructorsAtAll; public class UsingClassMockBehaviour extends UsingMiniMock { @@ -23,46 +21,7 @@ ensureThat(expected, eq(actual)); } - public void shouldBeAbleToMockClassesProvidingConstructorArgs() { - Object expected = new Object(); - - Mock mock = classMock.mock(AClassWithAReallyNastyConstructor.class, "foo", - new Class[] { - String.class, - int.class, - char.class, - Object[].class, - AClassWithNoConstructorsAtAll.class}, - new Object[] { - "", - new Integer(0), - new Character(' '), - new Object[0], - AClassWithNoConstructorsAtAll.INSTANCE}); - mock.expects("getSomething").will(returnValue(expected)); - - Object actual = ((AClassWithAReallyNastyConstructor)mock).getSomething(); - ensureThat(expected, eq(actual)); - } - public void shouldBeAbleToStubClasses() { throw new PendingException(); } - - public static class AClassWithAReallyNastyConstructor { - public AClassWithAReallyNastyConstructor( - String anObject, - int primitive, - char primitive2, - Object[] array, - AClassWithNoConstructorsAtAll someEnum) { - anObject.compareTo(someEnum.toString()); - int i = primitive + array.length; - i++; // just to stop the unused warnings - } - - public Object getSomething() { - return null; - } - } }
Modified: trunk/extensions/classmocks/src/java/jbehave/extensions/classmock/ClassMockObject.java (594 => 595)
--- trunk/extensions/classmocks/src/java/jbehave/extensions/classmock/ClassMockObject.java 2006-11-30 07:26:29 UTC (rev 594) +++ trunk/extensions/classmocks/src/java/jbehave/extensions/classmock/ClassMockObject.java 2006-11-30 11:53:58 UTC (rev 595) @@ -1,6 +1,5 @@ package jbehave.extensions.classmock; -import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; @@ -8,11 +7,11 @@ import jbehave.core.minimock.MiniMockObject; import jbehave.core.mock.ExpectationRegistry; import jbehave.core.mock.Mock; -import net.sf.cglib.core.CodeGenerationException; -import net.sf.cglib.proxy.Enhancer; -import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; +import com.thoughtworks.proxy.Invoker; +import com.thoughtworks.proxy.factory.CglibProxyFactory; + /** * Minimal implementation of mock object for classes, inspired by <a href="" * @@ -20,120 +19,39 @@ */ class ClassMockObject extends MiniMockObject { - private final Class[] constructorArgClasses; - private final Object[] constructorArgs; - - private ClassMockObject(Class type, String name, Class[] constructorArgClasses, Object[] constructorArgs) { + private ClassMockObject(Class type, String name) { super(type, name); - this.constructorArgClasses = constructorArgClasses; - this.constructorArgs = constructorArgs; } /** get the mocked instance */ public Object proxy() { - Enhancer enhancer = new Enhancer(); - enhancer.setClassLoader(getType().getClassLoader()); - enhancer.setSuperclass(getType()); - enhancer.setCallback(new ExpectationHandlerDelegate()); - return enhancer.create(constructorArgClasses, constructorArgs); - } - - public static Mock mockClass(Class type, String name) { - Class[] constructorArgClasses = getConstructorArgClasses(type); - Object[] constructorArgs = createConstructorArgsFor(constructorArgClasses); - return createMockClass(type, name, constructorArgClasses, constructorArgs); - + return new CglibProxyFactory().createProxy(new Class[] {getType()}, new ExpectationHandlerDelegate()); } - - public static Mock mockClass(final Class type, final String name, Class[] constructorArgClasses, Object[] constructorArgs) { - return createMockClass(type, name, constructorArgClasses, constructorArgs); - } - - private static Mock createMockClass(final Class type, final String name, final Class[] constructorArgClasses, final Object[] constructorArgs) { + + public static Mock mockClass(final Class type, final String name) { if (type.getDeclaringClass() != null && !Modifier.isStatic(type.getModifiers())) { throw new IllegalArgumentException("cannot mock non-static inner class " + type.getName()); } - Enhancer enhancer = new Enhancer(); - enhancer.setSuperclass(type); - enhancer.setClassLoader(Mock.class.getClassLoader()); - enhancer.setInterfaces(new Class[]{Mock.class, ExpectationRegistry.class}); - enhancer.setCallback(new MethodInterceptor() { - final ClassMockObject mock = new ClassMockObject(type, name, constructorArgClasses, constructorArgs); - - public Object intercept(Object thisProxy, Method method, Object[] args, MethodProxy superProxy) throws Throwable - { - try { - Class targetClass = method.getDeclaringClass(); - return (targetClass.isAssignableFrom(type)) - ? method.invoke(mock.proxy(), args) - : method.invoke(mock, args); - } - catch (InvocationTargetException e) { - throw e.getTargetException(); - } - } + return (Mock) new CglibProxyFactory().createProxy(new Class[]{type, Mock.class, ExpectationRegistry.class}, + new Invoker() { + final ClassMockObject mock = new ClassMockObject(type, name); + + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + try { + Class targetClass = method.getDeclaringClass(); + return (targetClass.isAssignableFrom(type)) + ? method.invoke(mock.proxy(), args) + : method.invoke(mock, args); + } + catch (InvocationTargetException e) { + throw e.getTargetException(); + } + } }); - - try { - return (Mock) enhancer.create(constructorArgClasses, constructorArgs); - } catch (CodeGenerationException e) { - // Does this in Eclipse, but... - if (e.getCause() instanceof NullPointerException) { - throw caughtANullPointer(type, e); - } else { - throw e; - } - } catch (NullPointerException e) { - // For some reason, it does this on the command line - // (calls Enhancer.nextInstance() instead of Enhancer.firstInstance() ) - throw caughtANullPointer(type, e); - } } - private static IllegalArgumentException caughtANullPointer(final Class type, Throwable e) { - return new IllegalArgumentException("Caught a NullPointerException while trying to mock a " + type + ". This could be caused " + - "because a constructor argument that couldn't be instantiated was used in the constructor. Have you tried " + - "providing constructor arguments?"); - } - - - private static Class[] getConstructorArgClasses(Class type) { - Constructor[] constructors = type.getDeclaredConstructors(); - if (constructors.length == 0) { - constructors = type.getConstructors(); - } - if (constructors.length == 0) { - throw new IllegalArgumentException("No constructors available for class " + type); - } - if (Modifier.isPrivate(constructors[0].getModifiers())) { - try { - constructors[0].setAccessible(true); - } catch (SecurityException e) { - throw new IllegalArgumentException("No constructors available for class " + type); - } - } - return constructors[0].getParameterTypes(); - } - - private static Object[] createConstructorArgsFor(Class[] constructorArgClasses) { - Object[] args = new Object[constructorArgClasses.length]; - ConstructorFactory constructorFactory = new ConstructorFactory(); - - for (int i = 0; i < args.length; i++) { - Class clazz = constructorArgClasses[i]; - try { - Object result = constructorFactory.construct(clazz); - args[i] = result; - } catch (Exception e) { - throw new RuntimeException("Could not create constructor argument for class " + constructorArgClasses[i] + " at index " + i, e); - } - } - - return args; - } - - private class ExpectationHandlerDelegate extends ExpectationHandler implements MethodInterceptor { + private class ExpectationHandlerDelegate extends ExpectationHandler implements Invoker { public Object intercept(Object thisProxy, Method method, Object[] args, MethodProxy superProxy) throws Throwable { return this.invoke(thisProxy, method, args); }
Modified: trunk/extensions/classmocks/src/java/jbehave/extensions/classmock/UsingClassMock.java (594 => 595)
--- trunk/extensions/classmocks/src/java/jbehave/extensions/classmock/UsingClassMock.java 2006-11-30 07:26:29 UTC (rev 594) +++ trunk/extensions/classmocks/src/java/jbehave/extensions/classmock/UsingClassMock.java 2006-11-30 11:53:58 UTC (rev 595) @@ -8,12 +8,4 @@ protected Mock createMock(Class type, String name) { return ClassMockObject.mockClass(type, name); } - - public Mock mock(Class type, Class[] argTypes, Object[] args) { - return mock(type, type.getName(), argTypes, args); - } - - public Mock mock(Class type, String name, Class[] argTypes, Object[] args) { - return ClassMockObject.mockClass(type, name, argTypes, args); - } }
Added: trunk/lib/extensions/proxytoys-0.2.1.jar
(Binary files differ)
To unsubscribe from this list please visit:
