http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/main/java/org/waveprotocol/wave/model/testing/WaveletDataFactory.java ---------------------------------------------------------------------- diff --git a/wave/src/main/java/org/waveprotocol/wave/model/testing/WaveletDataFactory.java b/wave/src/main/java/org/waveprotocol/wave/model/testing/WaveletDataFactory.java deleted file mode 100644 index bf8ff93..0000000 --- a/wave/src/main/java/org/waveprotocol/wave/model/testing/WaveletDataFactory.java +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.waveprotocol.wave.model.testing; - - -import org.waveprotocol.wave.model.id.IdGenerator; -import org.waveprotocol.wave.model.id.WaveId; -import org.waveprotocol.wave.model.id.WaveletId; -import org.waveprotocol.wave.model.version.HashedVersion; -import org.waveprotocol.wave.model.wave.ParticipantId; -import org.waveprotocol.wave.model.wave.data.ObservableWaveletData; -import org.waveprotocol.wave.model.wave.data.WaveletData; -import org.waveprotocol.wave.model.wave.data.impl.EmptyWaveletSnapshot; - -/** - * Exposes any {@link ObservableWaveletData.Factory} as a {@link Factory}, by - * injecting suitable dependencies for testing. - * - */ -public final class WaveletDataFactory<T extends WaveletData> implements Factory<T> { - private final static WaveId WAVE_ID; - private final static WaveletId WAVELET_ID; - private static final ParticipantId PARTICIPANT_ID = new ParticipantId("f...@example.com"); - - static { - IdGenerator gen = FakeIdGenerator.create(); - WAVE_ID = gen.newWaveId(); - WAVELET_ID = gen.newConversationWaveletId(); - } - - private final WaveletData.Factory<T> factory; - - private WaveletDataFactory(WaveletData.Factory<T> factory) { - this.factory = factory; - } - - public static <T extends WaveletData> Factory<T> of(WaveletData.Factory<T> factory) { - return new WaveletDataFactory<T>(factory); - } - - @Override - public T create() { - return factory.create(new EmptyWaveletSnapshot(WAVE_ID, WAVELET_ID, PARTICIPANT_ID, - HashedVersion.unsigned(0), 0)); - } -}
http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/main/resources/org/apache/wave/box/server/rpc/avatar/unknown.jpg ---------------------------------------------------------------------- diff --git a/wave/src/main/resources/org/apache/wave/box/server/rpc/avatar/unknown.jpg b/wave/src/main/resources/org/apache/wave/box/server/rpc/avatar/unknown.jpg new file mode 100644 index 0000000..0f39513 Binary files /dev/null and b/wave/src/main/resources/org/apache/wave/box/server/rpc/avatar/unknown.jpg differ http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/main/resources/org/waveprotocol/box/attachment/Attachment.gwt.xml ---------------------------------------------------------------------- diff --git a/wave/src/main/resources/org/waveprotocol/box/attachment/Attachment.gwt.xml b/wave/src/main/resources/org/waveprotocol/box/attachment/Attachment.gwt.xml index 2783343..3a5d2d1 100644 --- a/wave/src/main/resources/org/waveprotocol/box/attachment/Attachment.gwt.xml +++ b/wave/src/main/resources/org/waveprotocol/box/attachment/Attachment.gwt.xml @@ -23,4 +23,5 @@ <module> <inherits name="org.waveprotocol.wave.communication.Communication"/> <source path="" excludes="gson/** proto/**"/> + <source path="" excludes="**/AttachmentProto.java"/> </module> http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/main/resources/org/waveprotocol/box/common/comms/WaveClientRpc.gwt.xml ---------------------------------------------------------------------- diff --git a/wave/src/main/resources/org/waveprotocol/box/common/comms/WaveClientRpc.gwt.xml b/wave/src/main/resources/org/waveprotocol/box/common/comms/WaveClientRpc.gwt.xml index 7393ff6..cfc5633 100644 --- a/wave/src/main/resources/org/waveprotocol/box/common/comms/WaveClientRpc.gwt.xml +++ b/wave/src/main/resources/org/waveprotocol/box/common/comms/WaveClientRpc.gwt.xml @@ -25,4 +25,5 @@ <!-- DTO deps below. --> <inherits name="org.waveprotocol.wave.communication.Communication"/> <source path="" excludes="gson/** proto/**"/> + <source path="" excludes="**/WaveClientRpc.java"/> </module> http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/main/resources/org/waveprotocol/box/profile/Profile.gwt.xml ---------------------------------------------------------------------- diff --git a/wave/src/main/resources/org/waveprotocol/box/profile/Profile.gwt.xml b/wave/src/main/resources/org/waveprotocol/box/profile/Profile.gwt.xml index b02f733..49ad4bb 100644 --- a/wave/src/main/resources/org/waveprotocol/box/profile/Profile.gwt.xml +++ b/wave/src/main/resources/org/waveprotocol/box/profile/Profile.gwt.xml @@ -24,5 +24,5 @@ <!-- DTO deps below. --> <inherits name="org.waveprotocol.wave.communication.Communication"/> <source path="" excludes="gson/** proto/**"/> - <source path=""/> + <source path="" excludes="**/ProfilesProto.java"/> </module> http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/main/resources/org/waveprotocol/box/search/Search.gwt.xml ---------------------------------------------------------------------- diff --git a/wave/src/main/resources/org/waveprotocol/box/search/Search.gwt.xml b/wave/src/main/resources/org/waveprotocol/box/search/Search.gwt.xml index 7393ff6..ad022d2 100644 --- a/wave/src/main/resources/org/waveprotocol/box/search/Search.gwt.xml +++ b/wave/src/main/resources/org/waveprotocol/box/search/Search.gwt.xml @@ -25,4 +25,5 @@ <!-- DTO deps below. --> <inherits name="org.waveprotocol.wave.communication.Communication"/> <source path="" excludes="gson/** proto/**"/> + <source path="" excludes="**/SearchProto.java"/> </module> http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/main/resources/org/waveprotocol/box/stat/Stat.gwt.xml ---------------------------------------------------------------------- diff --git a/wave/src/main/resources/org/waveprotocol/box/stat/Stat.gwt.xml b/wave/src/main/resources/org/waveprotocol/box/stat/Stat.gwt.xml index a459a43..3139114 100644 --- a/wave/src/main/resources/org/waveprotocol/box/stat/Stat.gwt.xml +++ b/wave/src/main/resources/org/waveprotocol/box/stat/Stat.gwt.xml @@ -12,5 +12,6 @@ <!-- limitations under the License. --> <module> + <inherits name="com.google.common.collect.Collect"/> <source path=""/> </module> http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/main/resources/org/waveprotocol/wave/client/doodad/Doodad.gwt.xml ---------------------------------------------------------------------- diff --git a/wave/src/main/resources/org/waveprotocol/wave/client/doodad/Doodad.gwt.xml b/wave/src/main/resources/org/waveprotocol/wave/client/doodad/Doodad.gwt.xml index 26cf342..01c645b 100644 --- a/wave/src/main/resources/org/waveprotocol/wave/client/doodad/Doodad.gwt.xml +++ b/wave/src/main/resources/org/waveprotocol/wave/client/doodad/Doodad.gwt.xml @@ -29,6 +29,7 @@ <inherits name="org.waveprotocol.wave.client.widget.button.Button" /> <inherits name="org.waveprotocol.wave.model.conversation.Conversation" /> <inherits name="org.waveprotocol.wave.util.escapers.Escapers" /> +<inherits name="org.waveprotocol.box.webclient.WebClient"/> <source path=""/> http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/main/resources/org/waveprotocol/wave/client/editor/Editor.gwt.xml ---------------------------------------------------------------------- diff --git a/wave/src/main/resources/org/waveprotocol/wave/client/editor/Editor.gwt.xml b/wave/src/main/resources/org/waveprotocol/wave/client/editor/Editor.gwt.xml index 24af85f..a0a7a4b 100644 --- a/wave/src/main/resources/org/waveprotocol/wave/client/editor/Editor.gwt.xml +++ b/wave/src/main/resources/org/waveprotocol/wave/client/editor/Editor.gwt.xml @@ -29,6 +29,7 @@ <inherits name="org.waveprotocol.wave.client.common.scrub.Scrub" /> <inherits name="org.waveprotocol.wave.client.common.util.Util" /> <inherits name="org.waveprotocol.wave.client.debug.logger.Logger" /> +<inherits name="org.waveprotocol.wave.client.doodad.Doodad" /> <inherits name="org.waveprotocol.wave.client.editor.constants.Constants" /> <inherits name="org.waveprotocol.wave.client.editor.content.paragraph.constants.Constants" /> <inherits name="org.waveprotocol.wave.client.editor.selection.html.Html" /> http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/main/resources/org/waveprotocol/wave/client/scheduler/Scheduler.gwt.xml ---------------------------------------------------------------------- diff --git a/wave/src/main/resources/org/waveprotocol/wave/client/scheduler/Scheduler.gwt.xml b/wave/src/main/resources/org/waveprotocol/wave/client/scheduler/Scheduler.gwt.xml index 2d013bd..57ce7cd 100644 --- a/wave/src/main/resources/org/waveprotocol/wave/client/scheduler/Scheduler.gwt.xml +++ b/wave/src/main/resources/org/waveprotocol/wave/client/scheduler/Scheduler.gwt.xml @@ -20,7 +20,10 @@ --> -<module><inherits name="com.google.gwt.user.User" /><inherits name="org.waveprotocol.wave.client.common.util.Util" /> <source path=""/> +<module> + <inherits name="com.google.gwt.user.User" /> + <inherits name="org.waveprotocol.wave.client.common.util.Util" /> + <inherits name="org.waveprotocol.box.stat.Stat" /> + <source path=""/> <source path="knobs"/> - </module> http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/main/resources/org/waveprotocol/wave/client/scheduler/testing/Testing.gwt.xml ---------------------------------------------------------------------- diff --git a/wave/src/main/resources/org/waveprotocol/wave/client/scheduler/testing/Testing.gwt.xml b/wave/src/main/resources/org/waveprotocol/wave/client/scheduler/testing/Testing.gwt.xml index 1b37066..1b0896c 100644 --- a/wave/src/main/resources/org/waveprotocol/wave/client/scheduler/testing/Testing.gwt.xml +++ b/wave/src/main/resources/org/waveprotocol/wave/client/scheduler/testing/Testing.gwt.xml @@ -20,6 +20,8 @@ --> -<module><inherits name="com.google.gwt.user.User" /> <source path=""/> +<module><inherits name="com.google.gwt.user.User" /> + <inherits name="org.waveprotocol.wave.client.scheduler.Scheduler"/> + <source path=""/> </module> http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/main/resources/org/waveprotocol/wave/client/wavepanel/WavePanel.gwt.xml ---------------------------------------------------------------------- diff --git a/wave/src/main/resources/org/waveprotocol/wave/client/wavepanel/WavePanel.gwt.xml b/wave/src/main/resources/org/waveprotocol/wave/client/wavepanel/WavePanel.gwt.xml index 1b37066..30524e2 100644 --- a/wave/src/main/resources/org/waveprotocol/wave/client/wavepanel/WavePanel.gwt.xml +++ b/wave/src/main/resources/org/waveprotocol/wave/client/wavepanel/WavePanel.gwt.xml @@ -20,6 +20,9 @@ --> -<module><inherits name="com.google.gwt.user.User" /> <source path=""/> +<module><inherits name="com.google.gwt.user.User" /> + <inherits name="org.waveprotocol.wave.client.uibuilder.UiBuilder"/> + <inherits name="org.waveprotocol.box.stat.Stat"/> + <source path=""/> </module> http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/main/resources/org/waveprotocol/wave/client/wavepanel/event/Event.gwt.xml ---------------------------------------------------------------------- diff --git a/wave/src/main/resources/org/waveprotocol/wave/client/wavepanel/event/Event.gwt.xml b/wave/src/main/resources/org/waveprotocol/wave/client/wavepanel/event/Event.gwt.xml index 1ef9aa9..bf53a20 100644 --- a/wave/src/main/resources/org/waveprotocol/wave/client/wavepanel/event/Event.gwt.xml +++ b/wave/src/main/resources/org/waveprotocol/wave/client/wavepanel/event/Event.gwt.xml @@ -20,6 +20,9 @@ --> -<module><inherits name="com.google.gwt.user.User" /><inherits name="com.google.common.base.Base" /><inherits name="org.waveprotocol.wave.client.common.util.Util" /><inherits name="org.waveprotocol.wave.client.uibuilder.UiBuilder" /><inherits name="org.waveprotocol.wave.client.widget.common.Common" /><inherits name="org.waveprotocol.wave.model.util.Util" /> <source path=""/> +<module><inherits name="com.google.gwt.user.User" /><inherits name="com.google.common.base.Base" /><inherits name="org.waveprotocol.wave.client.common.util.Util" /><inherits name="org.waveprotocol.wave.client.uibuilder.UiBuilder" /><inherits name="org.waveprotocol.wave.client.widget.common.Common" /><inherits name="org.waveprotocol.wave.model.util.Util" /> + <inherits name="org.waveprotocol.box.stat.Stat"/> + <inherits name="org.waveprotocol.box.stat.Stat"/> + <source path=""/> </module> http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/test/java/com/google/wave/api/BlipRobotTest.java ---------------------------------------------------------------------- diff --git a/wave/src/test/java/com/google/wave/api/BlipRobotTest.java b/wave/src/test/java/com/google/wave/api/BlipRobotTest.java index d8b33f8..1d48b25 100644 --- a/wave/src/test/java/com/google/wave/api/BlipRobotTest.java +++ b/wave/src/test/java/com/google/wave/api/BlipRobotTest.java @@ -458,7 +458,7 @@ public class BlipRobotTest extends TestCase { Blip expectedBlip = new Blip("blip1", Arrays.asList("blip2", "blip3"), "\nhello world!\n another line", Arrays.asList("ro...@test.com", "u...@test.com"), - "u...@test.com", 1000l, 123l, null, null, Arrays.asList(new Annotation("key", "val", 2, 3)), + "u...@test.com", 1000l, 123l, null, "<some string>", Arrays.asList(new Annotation("key", "val", 2, 3)), elements, new ArrayList<String>(), wavelet); Blip actualBlip = Blip.deserialize(wavelet.getOperationQueue(), wavelet, http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/test/java/org/waveprotocol/box/server/frontend/ClientFrontendImplTest.java ---------------------------------------------------------------------- diff --git a/wave/src/test/java/org/waveprotocol/box/server/frontend/ClientFrontendImplTest.java b/wave/src/test/java/org/waveprotocol/box/server/frontend/ClientFrontendImplTest.java index 8a3f1d6..54556e8 100644 --- a/wave/src/test/java/org/waveprotocol/box/server/frontend/ClientFrontendImplTest.java +++ b/wave/src/test/java/org/waveprotocol/box/server/frontend/ClientFrontendImplTest.java @@ -330,8 +330,7 @@ public class ClientFrontendImplTest extends TestCase { private static List<TransformedWaveletDelta> isDeltasStartingAt(final long version) { return argThat(new ArgumentMatcher<List<TransformedWaveletDelta>>() { - @Override - public boolean matches(Object sequence) { + public boolean matches(List<TransformedWaveletDelta> sequence) { if (sequence != null) { DeltaSequence s = (DeltaSequence) sequence; return (s.size() > 0) && (s.getStartVersion() == version); http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/test/java/org/waveprotocol/box/server/robots/active/ActiveApiServletTest.java ---------------------------------------------------------------------- diff --git a/wave/src/test/java/org/waveprotocol/box/server/robots/active/ActiveApiServletTest.java b/wave/src/test/java/org/waveprotocol/box/server/robots/active/ActiveApiServletTest.java index 9c60294..540ed7b 100644 --- a/wave/src/test/java/org/waveprotocol/box/server/robots/active/ActiveApiServletTest.java +++ b/wave/src/test/java/org/waveprotocol/box/server/robots/active/ActiveApiServletTest.java @@ -119,7 +119,7 @@ public class ActiveApiServletTest extends TestCase { String operationId = "op1"; OperationRequest operation = new OperationRequest("wavelet.create", operationId); List<OperationRequest> operations = Collections.singletonList(operation); - when(robotSerializer.deserializeOperations(anyString())).thenReturn(operations); + when(robotSerializer.deserializeOperations(any())).thenReturn(operations); String responseValue = "response value"; when(robotSerializer.serialize(any(), any(Type.class), any(ProtocolVersion.class))).thenReturn( responseValue); http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/test/java/org/waveprotocol/box/server/robots/dataapi/DataApiServletTest.java ---------------------------------------------------------------------- diff --git a/wave/src/test/java/org/waveprotocol/box/server/robots/dataapi/DataApiServletTest.java b/wave/src/test/java/org/waveprotocol/box/server/robots/dataapi/DataApiServletTest.java index 40e2e63..3bd3e52 100644 --- a/wave/src/test/java/org/waveprotocol/box/server/robots/dataapi/DataApiServletTest.java +++ b/wave/src/test/java/org/waveprotocol/box/server/robots/dataapi/DataApiServletTest.java @@ -121,7 +121,7 @@ public class DataApiServletTest extends TestCase { String operationId = "op1"; OperationRequest operation = new OperationRequest("wavelet.create", operationId); List<OperationRequest> operations = Collections.singletonList(operation); - when(robotSerializer.deserializeOperations(anyString())).thenReturn(operations); + when(robotSerializer.deserializeOperations(any())).thenReturn(operations); String responseValue = "response value"; when(robotSerializer.serialize(any(), any(Type.class), any(ProtocolVersion.class))).thenReturn( responseValue); http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/test/java/org/waveprotocol/box/server/robots/operations/FetchProfilesServiceTest.java ---------------------------------------------------------------------- diff --git a/wave/src/test/java/org/waveprotocol/box/server/robots/operations/FetchProfilesServiceTest.java b/wave/src/test/java/org/waveprotocol/box/server/robots/operations/FetchProfilesServiceTest.java index 6b55728..da6fc93 100644 --- a/wave/src/test/java/org/waveprotocol/box/server/robots/operations/FetchProfilesServiceTest.java +++ b/wave/src/test/java/org/waveprotocol/box/server/robots/operations/FetchProfilesServiceTest.java @@ -19,7 +19,7 @@ package org.waveprotocol.box.server.robots.operations; -import static org.mockito.Matchers.argThat; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/test/java/org/waveprotocol/box/server/robots/operations/SearchServiceTest.java ---------------------------------------------------------------------- diff --git a/wave/src/test/java/org/waveprotocol/box/server/robots/operations/SearchServiceTest.java b/wave/src/test/java/org/waveprotocol/box/server/robots/operations/SearchServiceTest.java index 7b2f848..bc5113f 100644 --- a/wave/src/test/java/org/waveprotocol/box/server/robots/operations/SearchServiceTest.java +++ b/wave/src/test/java/org/waveprotocol/box/server/robots/operations/SearchServiceTest.java @@ -19,7 +19,7 @@ package org.waveprotocol.box.server.robots.operations; -import static org.mockito.Matchers.argThat; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/test/java/org/waveprotocol/box/server/robots/passive/RobotTest.java ---------------------------------------------------------------------- diff --git a/wave/src/test/java/org/waveprotocol/box/server/robots/passive/RobotTest.java b/wave/src/test/java/org/waveprotocol/box/server/robots/passive/RobotTest.java index d551a3e..c5fa248 100644 --- a/wave/src/test/java/org/waveprotocol/box/server/robots/passive/RobotTest.java +++ b/wave/src/test/java/org/waveprotocol/box/server/robots/passive/RobotTest.java @@ -204,7 +204,7 @@ public class RobotTest extends TestCase { EventMessageBundle messages = new EventMessageBundle(ROBOT_NAME.toEmailAddress(), ""); messages.addEvent(new DocumentChangedEvent(null, null, ALEX.getAddress(), 0L, "b+1234")); when(eventGenerator.generateEvents( - any(WaveletAndDeltas.class), anyMap(), any(EventDataConverter.class))).thenReturn(messages); + any(), anyMap(), any())).thenReturn(messages); OperationRequest op = new OperationRequest("wavelet.fetch", "op1"); List<OperationRequest> ops = Collections.singletonList(op); http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/test/java/org/waveprotocol/box/server/robots/testing/OperationServiceHelper.java ---------------------------------------------------------------------- diff --git a/wave/src/test/java/org/waveprotocol/box/server/robots/testing/OperationServiceHelper.java b/wave/src/test/java/org/waveprotocol/box/server/robots/testing/OperationServiceHelper.java new file mode 100644 index 0000000..814f972 --- /dev/null +++ b/wave/src/test/java/org/waveprotocol/box/server/robots/testing/OperationServiceHelper.java @@ -0,0 +1,120 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.waveprotocol.box.server.robots.testing; + +import static org.mockito.Mockito.mock; + +import com.google.wave.api.data.converter.EventDataConverter; +import com.google.wave.api.data.converter.v22.EventDataConverterV22; + +import org.waveprotocol.box.server.robots.OperationContextImpl; +import org.waveprotocol.box.server.robots.RobotWaveletData; +import org.waveprotocol.box.server.robots.operations.OperationService; +import org.waveprotocol.box.server.robots.util.ConversationUtil; +import org.waveprotocol.box.server.waveserver.WaveletProvider; +import org.waveprotocol.wave.model.conversation.ObservableConversation; +import org.waveprotocol.wave.model.conversation.WaveletBasedConversation; +import org.waveprotocol.wave.model.id.IdURIEncoderDecoder; +import org.waveprotocol.wave.model.id.WaveletName; +import org.waveprotocol.wave.model.operation.SilentOperationSink; +import org.waveprotocol.wave.model.operation.wave.BasicWaveletOperationContextFactory; +import org.waveprotocol.wave.model.operation.wave.WaveletOperation; +import org.waveprotocol.wave.model.testing.BasicFactories; +import org.waveprotocol.wave.model.testing.FakeIdGenerator; +import org.waveprotocol.wave.model.version.HashedVersionFactory; +import org.waveprotocol.wave.model.version.HashedVersionFactoryImpl; +import org.waveprotocol.wave.model.wave.ParticipantId; +import org.waveprotocol.wave.model.wave.ParticipationHelper; +import org.waveprotocol.wave.model.wave.data.DocumentFactory; +import org.waveprotocol.wave.model.wave.data.DocumentOperationSink; +import org.waveprotocol.wave.model.wave.data.ObservableWaveletData; +import org.waveprotocol.wave.model.wave.data.WaveletData; +import org.waveprotocol.wave.model.wave.data.impl.EmptyWaveletSnapshot; +import org.waveprotocol.wave.model.wave.data.impl.WaveletDataImpl; +import org.waveprotocol.wave.model.wave.opbased.OpBasedWavelet; +import org.waveprotocol.wave.util.escapers.jvm.JavaUrlCodec; + +/** + * Helper for testing {@link OperationService}. Puts a single empty + * conversational wavelet with one participant in the operation context. + * + * @author ljvder...@google.com (Lennard de Rijk) + */ +public class OperationServiceHelper { + + private static final IdURIEncoderDecoder URI_CODEC = + new IdURIEncoderDecoder(new JavaUrlCodec()); + private static final HashedVersionFactory HASH_FACTORY = new HashedVersionFactoryImpl(URI_CODEC); + private static final DocumentFactory<? extends DocumentOperationSink> DOCUMENT_FACTORY = + BasicFactories.observablePluggableMutableDocumentFactory(); + + private final WaveletProvider waveletProvider; + private final OperationContextImpl context; + + /** + * Constructs a new {@link OperationServiceHelper} with a wavelet with the + * name and participant that are passed in. + * + * @param waveletName the name of the empty wavelet to open in the context. + * @param participant the participant that should be on that empty wavelet. + */ + public OperationServiceHelper(WaveletName waveletName, ParticipantId participant) { + waveletProvider = mock(WaveletProvider.class); + EventDataConverter converter = new EventDataConverterV22(); + + ObservableWaveletData waveletData = WaveletDataImpl.Factory.create(DOCUMENT_FACTORY).create( + new EmptyWaveletSnapshot(waveletName.waveId, waveletName.waveletId, participant, + HASH_FACTORY.createVersionZero(waveletName), 0L)); + waveletData.addParticipant(participant); + + BasicWaveletOperationContextFactory CONTEXT_FACTORY = + new BasicWaveletOperationContextFactory(participant); + + SilentOperationSink<WaveletOperation> executor = + SilentOperationSink.Executor.<WaveletOperation, WaveletData>build(waveletData); + OpBasedWavelet wavelet = + new OpBasedWavelet(waveletData.getWaveId(), waveletData, CONTEXT_FACTORY, + ParticipationHelper.DEFAULT, executor, SilentOperationSink.VOID); + + // Make a conversation with an empty root blip + WaveletBasedConversation.makeWaveletConversational(wavelet); + ConversationUtil conversationUtil = new ConversationUtil(FakeIdGenerator.create()); + ObservableConversation conversation = conversationUtil.buildConversation(wavelet).getRoot(); + conversation.getRootThread().appendBlip(); + + context = new OperationContextImpl(waveletProvider, converter, conversationUtil); + context.putWavelet(waveletName.waveId, waveletName.waveletId, + new RobotWaveletData(waveletData, HASH_FACTORY.createVersionZero(waveletName))); + } + + /** + * @return the {@link WaveletProvider} mock + */ + public WaveletProvider getWaveletProvider() { + return waveletProvider; + } + + /** + * @return the {@link OperationContextImpl} with the empty wavelet opened. + */ + public OperationContextImpl getContext() { + return context; + } +} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/test/java/org/waveprotocol/box/server/rpc/AuthenticationServletTest.java ---------------------------------------------------------------------- diff --git a/wave/src/test/java/org/waveprotocol/box/server/rpc/AuthenticationServletTest.java b/wave/src/test/java/org/waveprotocol/box/server/rpc/AuthenticationServletTest.java index 89c705e..3b006c2 100644 --- a/wave/src/test/java/org/waveprotocol/box/server/rpc/AuthenticationServletTest.java +++ b/wave/src/test/java/org/waveprotocol/box/server/rpc/AuthenticationServletTest.java @@ -185,7 +185,7 @@ public class AuthenticationServletTest extends TestCase { // Servlet control flow forces us to set these return values first and // verify the logged in user was set afterwards. if (expectSuccess) { - when(manager.getLoggedInUser(Mockito.any(HttpSession.class))).thenReturn(USER); + when(manager.getLoggedInUser(Mockito.any())).thenReturn(USER); when(session.getAttribute("user")).thenReturn(USER); } servlet.doPost(req, resp); http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/test/java/org/waveprotocol/box/server/rpc/testing/FakeServerRpcController.java ---------------------------------------------------------------------- diff --git a/wave/src/test/java/org/waveprotocol/box/server/rpc/testing/FakeServerRpcController.java b/wave/src/test/java/org/waveprotocol/box/server/rpc/testing/FakeServerRpcController.java new file mode 100644 index 0000000..fa45cd6 --- /dev/null +++ b/wave/src/test/java/org/waveprotocol/box/server/rpc/testing/FakeServerRpcController.java @@ -0,0 +1,84 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.waveprotocol.box.server.rpc.testing; + +import static org.waveprotocol.box.server.util.testing.TestingConstants.USER; + +import com.google.protobuf.RpcCallback; + +import org.waveprotocol.box.server.rpc.ServerRpcController; +import org.waveprotocol.wave.model.wave.ParticipantId; + + +/** + * An {@code RpcController} that just handles error text and failure condition. + */ +public class FakeServerRpcController implements ServerRpcController { + private boolean failed = false; + private String errorText = null; + + @Override + public String errorText() { + return errorText; + } + + @Override + public boolean failed() { + return failed; + } + + @Override + public boolean isCanceled() { + return false; + } + + @Override + public void notifyOnCancel(RpcCallback<Object> arg) { + } + + @Override + public void reset() { + failed = false; + errorText = null; + } + + @Override + public void setFailed(String error) { + failed = true; + errorText = error; + } + + @Override + public void startCancel() { + } + + @Override + public ParticipantId getLoggedInUser() { + return ParticipantId.ofUnsafe(USER); + } + + @Override + public void cancel() { + } + + @Override + public void run() { + } +} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/test/java/org/waveprotocol/box/server/util/testing/ExceptionLogHandler.java ---------------------------------------------------------------------- diff --git a/wave/src/test/java/org/waveprotocol/box/server/util/testing/ExceptionLogHandler.java b/wave/src/test/java/org/waveprotocol/box/server/util/testing/ExceptionLogHandler.java new file mode 100644 index 0000000..7ea3550 --- /dev/null +++ b/wave/src/test/java/org/waveprotocol/box/server/util/testing/ExceptionLogHandler.java @@ -0,0 +1,65 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.waveprotocol.box.server.util.testing; + +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogRecord; + +/** + * A log handler which throws a runtime exception at and above a set log level. + * Useful for catching erroneous conditions during testing, which are only + * reported to the logs. + * + * @author mk.mat...@gmail.com (Michael Kuntzman) + */ +public class ExceptionLogHandler extends Handler { + /** The integer value of the minimum fatal log level. */ + private final int fatalLevel; + + /** + * Constructs an ExceptionLogHandler that throws a runtime exception at and above the specified + * log level. + * + * @param fatalLevel the minimum log level for which to throw an exception. + */ + public ExceptionLogHandler(Level fatalLevel) { + this.fatalLevel = fatalLevel.intValue(); + } + + /** + * @throws RuntimeException if the log record is at or above the fatal log level. + */ + @Override + public void publish(LogRecord record) { + if (record.getLevel().intValue() >= fatalLevel) { + throw new RuntimeException(record.getLevel() + ": " + record.getMessage(), + record.getThrown()); + } + } + + @Override + public void flush() { + } + + @Override + public void close() { + } +} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/test/java/org/waveprotocol/box/server/util/testing/Matchers.java ---------------------------------------------------------------------- diff --git a/wave/src/test/java/org/waveprotocol/box/server/util/testing/Matchers.java b/wave/src/test/java/org/waveprotocol/box/server/util/testing/Matchers.java new file mode 100644 index 0000000..72be27a --- /dev/null +++ b/wave/src/test/java/org/waveprotocol/box/server/util/testing/Matchers.java @@ -0,0 +1,172 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.waveprotocol.box.server.util.testing; + +import org.hamcrest.Description; +import org.hamcrest.TypeSafeMatcher; + +import java.util.Collection; + +/** + * Additional matchers to go with JUnit4's assertThat and assumeThat. + * + * @author mk.mat...@gmail.com (Michael Kuntzman) + */ +// TODO(Michael): Maybe move this class to the libraries repository/branch. +public class Matchers { + /** + * Nicer aliases for some of the methods in this class, which may conflict with methods in other + * packages (potential conficts noted for each alias). + */ + public static class Aliases { + /** + * Alias for "containsString". May conflict with "org.mockito.Mockito.contains". + * + * @param substring to look for. + * @return a matcher for checking that a string contains the specified substring. + */ + public static TypeSafeMatcher<String> contains(final String substring) { + return containsString(substring); + } + + /** + * Alias for "matchesRegex". May conflict with "org.mockito.Mockito.matches". + * + * @param regularExpression to match against. + * @return a matcher for checking that a string matches the specified regular expression. + */ + public static TypeSafeMatcher<String> matches(final String regularExpression) { + return matchesRegex(regularExpression); + } + } + + /** + * A more user-friendly version of org.junit.matchers.JUnitMatchers.hasItem(T element). Allows a + * more verbose failure than assertTrue(collection.contains(item)). The matcher produces + * "Expected: a collection containing '...' got: '...'", whereas assertTrue produces merely + * "AssertionFailedError". + * Usage: static import, then assertThat(collection, contains(item)). + * + * @param item to look for. + * @return a matcher for checking that a collection contains the specified item. + */ + public static <T> TypeSafeMatcher<Collection<? super T>> contains(final T item) { + return new TypeSafeMatcher<Collection<? super T>>() { + @Override + public boolean matchesSafely(Collection<? super T> collection) { + return collection.contains(item); + } + + @Override + public void describeTo(Description description) { + description.appendText("a collection containing ").appendValue(item); + } + }; + } + + /** + * Same as JUnitMatchers.containsString. Allows a more verbose failure than + * assertTrue(str.contains(substring)). + * Usage: static import, then assertThat(str, containsString(substring)). + * + * @param substring to look for. + * @return a matcher for checking that a string contains the specified substring. + */ + public static TypeSafeMatcher<String> containsString(final String substring) { + return new TypeSafeMatcher<String>() { + @Override + public boolean matchesSafely(String str) { + return str.contains(substring); + } + + @Override + public void describeTo(Description description) { + description.appendText("a string containing ").appendValue(substring); + } + }; + } + + /** + * The negative version of "contains" for a collection. Allows a more verbose failure than + * assertFalse(collection.contains(item)). + * Usage: static import, then assertThat(collection, doesNotContain(item)). + * + * @param item to look for. + * @return a matcher for checking that a collection does not contain the specified item. + */ + public static <T> TypeSafeMatcher<Collection<? super T>> doesNotContain(final T item) { + return new TypeSafeMatcher<Collection<? super T>>() { + @Override + public boolean matchesSafely(Collection<? super T> collection) { + return !collection.contains(item); + } + + @Override + public void describeTo(Description description) { + description.appendText("a collection NOT containing ").appendValue(item); + } + }; + } + + /** + * The negative version of "contains" for a string (or "containsString"). Allows a more verbose + * failure than assertFalse(str.contains(substring)). + * Usage: static import, then assertThat(str, doesNotContain(substring)). + * + * @param substring to look for. + * @return a matcher for checking that a string contains the specified substring. + */ + public static TypeSafeMatcher<String> doesNotContain(final String substring) { + return new TypeSafeMatcher<String>() { + @Override + public boolean matchesSafely(String str) { + return !str.contains(substring); + } + + @Override + public void describeTo(Description description) { + description.appendText("a string NOT containing ").appendValue(substring); + } + }; + } + + /** + * Allows a more verbose failure than assertTrue(str.matches(regex)). The matcher produces + * "Expected: a string matching regex '...' got: '...'", whereas assertTrue produces merely + * "AssertionFailedError". + * Usage: static import, then assertThat(str, matchesRegex(regex)). + * + * @param regularExpression to match against. + * @return a matcher for checking that a string matches the specified regular expression. + */ + public static TypeSafeMatcher<String> matchesRegex(final String regularExpression) { + return new TypeSafeMatcher<String>() { + @Override + public boolean matchesSafely(String str) { + return str.matches(regularExpression); + } + + @Override + public void describeTo(Description description) { + description.appendText("a string matching regex ").appendValue(regularExpression); + } + }; + } +} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/test/java/org/waveprotocol/box/server/util/testing/TestingConstants.java ---------------------------------------------------------------------- diff --git a/wave/src/test/java/org/waveprotocol/box/server/util/testing/TestingConstants.java b/wave/src/test/java/org/waveprotocol/box/server/util/testing/TestingConstants.java new file mode 100644 index 0000000..ed0d95f --- /dev/null +++ b/wave/src/test/java/org/waveprotocol/box/server/util/testing/TestingConstants.java @@ -0,0 +1,66 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.waveprotocol.box.server.util.testing; + +import org.waveprotocol.wave.model.id.WaveId; +import org.waveprotocol.wave.model.id.WaveletId; +import org.waveprotocol.wave.model.id.WaveletName; +import org.waveprotocol.wave.model.wave.ParticipantId; + +/** + * Commonly used constants for unit testing. Some constants taken from + * previously existing test cases. + * + * @author mk.mat...@gmail.com (Michael Kuntzman) + */ +// TODO(Michael): Maybe move this class to the libraries repository/branch. +public interface TestingConstants { + public static final String BLIP_ID = "b+blip"; + + public static final String MESSAGE = "The quick brown fox jumps over the lazy dog"; + + public static final String MESSAGE2 = "Why's the rum gone?"; + + public static final String MESSAGE3 = "There is no spoon"; + + public static final String DOMAIN = "host.com"; + + public static final String OTHER_USER_NAME = "other"; + + public static final String OTHER_USER = OTHER_USER_NAME + "@" + DOMAIN; + + public static final ParticipantId OTHER_PARTICIPANT = new ParticipantId(OTHER_USER); + + public static final int PORT = 9876; + + public static final String USER_NAME = "user"; + + public static final String USER = USER_NAME + "@" + DOMAIN; + + public static final char[] PASSWORD = "password".toCharArray(); + + public static final ParticipantId PARTICIPANT = new ParticipantId(USER); + + public static final WaveId WAVE_ID = WaveId.of(DOMAIN, "w+wave"); + + public static final WaveletId WAVELET_ID = WaveletId.of(DOMAIN, "wavelet"); + + public static final WaveletName WAVELET_NAME = WaveletName.of(WAVE_ID, WAVELET_ID); +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/test/java/org/waveprotocol/wave/client/editor/extract/PasteFormatRendererGwtTest.java ---------------------------------------------------------------------- diff --git a/wave/src/test/java/org/waveprotocol/wave/client/editor/extract/PasteFormatRendererGwtTest.java b/wave/src/test/java/org/waveprotocol/wave/client/editor/extract/PasteFormatRendererGwtTest.java index 83d34c3..d5275cf 100644 --- a/wave/src/test/java/org/waveprotocol/wave/client/editor/extract/PasteFormatRendererGwtTest.java +++ b/wave/src/test/java/org/waveprotocol/wave/client/editor/extract/PasteFormatRendererGwtTest.java @@ -87,7 +87,7 @@ public class PasteFormatRendererGwtTest extends GWTTestCase { testHelper("<body><line/>before<line t=\"li\"/>one<line t=\"li\"/>two<line/>after</body>", "before<br><ul><li>one</li><li>two</li></ul>after<br>"); testHelper("<body><line t=\"li\"/><input>hello</input> world<line/>after</body>", - "<ul><li><span>hello</span> world</li></ul>after<br>"); + "<ul><li><span contentEditable=\"true\" style=\"white-space: pre-wrap;\" class=\"SWCNL\">hello</span> world</li></ul>after<br>"); } private void testHelper(String content, String expectedResult) { http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/test/java/org/waveprotocol/wave/client/editor/integration/ParagraphGwtTest.java ---------------------------------------------------------------------- diff --git a/wave/src/test/java/org/waveprotocol/wave/client/editor/integration/ParagraphGwtTest.java b/wave/src/test/java/org/waveprotocol/wave/client/editor/integration/ParagraphGwtTest.java index 8ea86ee..8fb854c 100644 --- a/wave/src/test/java/org/waveprotocol/wave/client/editor/integration/ParagraphGwtTest.java +++ b/wave/src/test/java/org/waveprotocol/wave/client/editor/integration/ParagraphGwtTest.java @@ -84,7 +84,7 @@ public class ParagraphGwtTest extends ElementTestBase { // testTaller("<p></p><p></p>", "<p></p>", minHeight); // testTaller("<p></p><p></p><p></p>", "<p></p><p></p>", minHeight); - testEqualHeight(format("<p></p>"), format("<p>aXj</p>")); + testEqualHeight(format("<p>a</p>"), format("<p>aXj</p>")); // testEqualHeight("<p></p><p></p>", "<p>aXj</p><p>aXjADFSG</p>"); testContentWrap("<p>|</p>"); http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/test/java/org/waveprotocol/wave/client/scheduler/IdempotentSchedulerTest.java ---------------------------------------------------------------------- diff --git a/wave/src/test/java/org/waveprotocol/wave/client/scheduler/IdempotentSchedulerTest.java b/wave/src/test/java/org/waveprotocol/wave/client/scheduler/IdempotentSchedulerTest.java index 27f062b..3082226 100644 --- a/wave/src/test/java/org/waveprotocol/wave/client/scheduler/IdempotentSchedulerTest.java +++ b/wave/src/test/java/org/waveprotocol/wave/client/scheduler/IdempotentSchedulerTest.java @@ -19,17 +19,17 @@ package org.waveprotocol.wave.client.scheduler; +import junit.framework.TestCase; import org.waveprotocol.wave.client.scheduler.Scheduler.IncrementalTask; -import org.jmock.Expectations; -import org.jmock.integration.junit3.MockObjectTestCase; +import static org.mockito.Mockito.*; /** * Test case for IdempotentScheduler. * */ -public class IdempotentSchedulerTest extends MockObjectTestCase { +public class IdempotentSchedulerTest extends TestCase { // Mocks. private IncrementalTask task; @@ -49,84 +49,57 @@ public class IdempotentSchedulerTest extends MockObjectTestCase { } public void testSchedulesItselfAsTheTask() { - checking(new Expectations() {{ - oneOf(timer).isScheduled(with(is)); - will(returnValue(false)); - oneOf(timer).scheduleRepeating(is, delay, delay); - }}); - is.schedule(); + + verify(timer, times(1)).isScheduled(is); + verify(timer, times(1)).scheduleRepeating(is, delay, delay); } public void testCancelsItselfAsTheTask() { - checking(new Expectations() {{ - oneOf(timer).isScheduled(with(is)); - will(returnValue(true)); - oneOf(timer).cancel(is); - }}); - + when(timer.isScheduled(is)).thenReturn(true); is.cancel(); + verify(timer, times(1)).cancel(is); } public void testSchedulerExecutesTask() { - checking(new Expectations() {{ - oneOf(task).execute(); - }}); - is.execute(); + verify(task, times(1)).execute(); } public void testMultipleScheduleCallsScheduleExactlyOnce() { - checking(new Expectations() {{ - oneOf(timer).isScheduled(with(is)); - will(returnValue(false)); - oneOf(timer).scheduleRepeating(is, delay, delay); - oneOf(timer).isScheduled(with(is)); - will(returnValue(true)); - }}); + when(timer.isScheduled(is)).thenReturn(true, false); is.schedule(); is.schedule(); + + verify(timer, times(2)).isScheduled(is); + verify(timer, times(1)).scheduleRepeating(is, delay, delay); } public void testCancelWillNotCancelIfNotScheduled() { - checking(new Expectations() {{ - oneOf(timer).isScheduled(with(is)); - will(returnValue(false)); - }}); - + when(timer.isScheduled(is)).thenReturn(false); is.cancel(); + verify(timer, never()).cancel(is); } public void testWillRescheduleAfterTaskCompletion() { - checking(new Expectations() {{ - oneOf(timer).isScheduled(with(is)); - will(returnValue(false)); - oneOf(timer).scheduleRepeating(is, delay, delay); - oneOf(task).execute(); - will(returnValue(false)); // Indicates termination - oneOf(timer).isScheduled(with(is)); - will(returnValue(false)); - oneOf(timer).scheduleRepeating(is, delay, delay); - }}); + when(timer.isScheduled(is)).thenReturn(false); + when(task.execute()).thenReturn(false); is.schedule(); is.execute(); // Simulates call by timer. is.schedule(); + + verify(timer, times(2)).scheduleRepeating(is, delay, delay); } public void testWillRescheduleAfterCancel() { - checking(new Expectations() {{ - oneOf(timer).isScheduled(with(is)); will(returnValue(false)); - oneOf(timer).scheduleRepeating(is, delay, delay); - oneOf(timer).isScheduled(with(is)); will(returnValue(true)); - oneOf(timer).cancel(is); - oneOf(timer).isScheduled(with(is)); - will(returnValue(false)); - oneOf(timer).scheduleRepeating(is, delay, delay); - }}); + when(timer.isScheduled(is)).thenReturn(false, true, false); is.schedule(); is.cancel(); is.schedule(); + + verify(timer, times(1)).cancel(is); + verify(timer, times(2)).scheduleRepeating(is, delay, delay); } } http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/test/java/org/waveprotocol/wave/client/scheduler/knobs/ControllerTest.java ---------------------------------------------------------------------- diff --git a/wave/src/test/java/org/waveprotocol/wave/client/scheduler/knobs/ControllerTest.java b/wave/src/test/java/org/waveprotocol/wave/client/scheduler/knobs/ControllerTest.java index 7cc062d..2f17a92 100644 --- a/wave/src/test/java/org/waveprotocol/wave/client/scheduler/knobs/ControllerTest.java +++ b/wave/src/test/java/org/waveprotocol/wave/client/scheduler/knobs/ControllerTest.java @@ -19,21 +19,21 @@ package org.waveprotocol.wave.client.scheduler.knobs; +import junit.framework.TestCase; import org.waveprotocol.wave.client.scheduler.Scheduler.Priority; import org.waveprotocol.wave.client.scheduler.Scheduler.Schedulable; - -import org.jmock.Expectations; -import org.jmock.integration.junit3.MockObjectTestCase; import org.waveprotocol.wave.model.util.ReadableStringSet; import java.util.Collection; +import static org.mockito.Mockito.*; + /** * Tests the controller components for the scheduler. * */ -public class ControllerTest extends MockObjectTestCase { +public class ControllerTest extends TestCase { /** * Stub implementation of a per-level UI control. Used both as a dummy and a @@ -107,54 +107,20 @@ public class ControllerTest extends MockObjectTestCase { knobView = mock(KnobView.class); knobsView = mock(KnobsView.class); stubView = new StubLevelView(); + for (Priority p : Priority.values()) { + when(knobsView.create(p)).thenReturn(p.equals(Priority.MEDIUM) ? stubView : new StubLevelView()); + } } - /** - * Tells jmock to accept the things that happen to the mock level-view - * when it gets injected into a level presenter. - */ - private void allowKnobViewSetup() { - /// Sigh, Jmock = tight coupling with impl details :( - checking(new Expectations() {{ - // Stuff that happens in constructor - one(knobView).init(with(any(KnobPresenter.class))); - one(knobView).enable(); - one(knobView).showCount(0); - one(knobView).hideJobs(); - }}); - } - - /** - * Tells jmock to accept the things that happen to the mock knob-view - * when it gets injected into a presenter. Also injects {@link #stubView} as - * the per-level view of the MEDIUM priority level. - */ - private void allowKnobsViewSetup() { - checking(new Expectations() {{ - for (Priority p : Priority.values()) { - one(knobsView).create(p); - will(returnValue(p.equals(Priority.MEDIUM) ? stubView : new StubLevelView())); - } - }}); - } - - // - // Tests below. - // - public void testLevelPresenterInitialStateAndClicking() { - allowKnobViewSetup(); KnobPresenter presenter = new KnobPresenter(knobView); - checking(new Expectations() {{ - one(knobView).disable(); - }}); presenter.onClicked(); + verify(knobView, times(1)).disable(); + - checking(new Expectations() {{ - one(knobView).enable(); - }}); presenter.onClicked(); + verify(knobView, times(2)).enable(); // is enabled by default } public void testLevelEnabledAndDisabled() { @@ -167,12 +133,10 @@ public class ControllerTest extends MockObjectTestCase { } public void testKnobsAddLevelForEachPriority() { - allowKnobsViewSetup(); KnobsPresenter presenter = new KnobsPresenter(knobsView); } public void testClickingOnLevelTogglesRunnability() { - allowKnobsViewSetup(); KnobsPresenter presenter = new KnobsPresenter(knobsView); assertNotNull(stubView.getListener()); @@ -184,7 +148,6 @@ public class ControllerTest extends MockObjectTestCase { } public void testUpdatingMediumJobCountUpdatesView() { - allowKnobsViewSetup(); KnobsPresenter presenter = new KnobsPresenter(knobsView); Schedulable a = new Schedulable(){}; http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/test/java/org/waveprotocol/wave/client/scheduler/testing/FakeTimerServiceTest.java ---------------------------------------------------------------------- diff --git a/wave/src/test/java/org/waveprotocol/wave/client/scheduler/testing/FakeTimerServiceTest.java b/wave/src/test/java/org/waveprotocol/wave/client/scheduler/testing/FakeTimerServiceTest.java index 83fd4de..580b25d 100644 --- a/wave/src/test/java/org/waveprotocol/wave/client/scheduler/testing/FakeTimerServiceTest.java +++ b/wave/src/test/java/org/waveprotocol/wave/client/scheduler/testing/FakeTimerServiceTest.java @@ -19,20 +19,19 @@ package org.waveprotocol.wave.client.scheduler.testing; +import junit.framework.TestCase; +import org.mockito.InOrder; import org.waveprotocol.wave.client.scheduler.Scheduler.IncrementalTask; import org.waveprotocol.wave.client.scheduler.Scheduler.Task; -import org.jmock.integration.junit3.MockObjectTestCase; -import org.jmock.Expectations; -import org.jmock.Sequence; +import static org.mockito.Mockito.*; /** * The FakeTimerService is a complicated enough fake that it deserves its own * tests. (Normally I wouldn't test fakes.) * */ - -public class FakeTimerServiceTest extends MockObjectTestCase { +public class FakeTimerServiceTest extends TestCase { private Task oneoff; private IncrementalTask repeating; private FakeTimerService timer; @@ -43,6 +42,7 @@ public class FakeTimerServiceTest extends MockObjectTestCase { oneoff = mock(Task.class, "oneoff"); repeating = mock(IncrementalTask.class, "repeating"); + when(repeating.execute()).thenReturn(true); timer = new FakeTimerService(); } @@ -50,31 +50,22 @@ public class FakeTimerServiceTest extends MockObjectTestCase { timer.scheduleDelayed(oneoff, 500); timer.scheduleRepeating(repeating, 0, 1000); - checking(new Expectations() {{ - one(oneoff).execute(); - exactly(2).of(repeating).execute(); - will(returnValue(true)); - }}); timer.tick(1000); timer.tick(500); timer.tick(499); - checking(new Expectations() {{ - one(repeating).execute(); - will(returnValue(true)); - }}); + verify(oneoff, times(1)).execute(); + verify(repeating, times(2)).execute(); + timer.tick(1); timer.tick(1); timer.tick(1); - checking(new Expectations() {{ - one(repeating).execute(); - will(returnValue(true)); - }}); + verify(repeating, times(3)).execute(); + timer.tick(999); - checking(new Expectations() {{ - exactly(3).of(repeating).execute(); - will(returnValue(true)); - }}); + verify(repeating, times(4)).execute(); + timer.tick(3000); + verify(repeating, times(7)).execute(); } public void testCancel() { @@ -83,22 +74,17 @@ public class FakeTimerServiceTest extends MockObjectTestCase { timer.scheduleRepeating(repeating, 0, 1000); timer.cancel(repeating); - checking(new Expectations() {{ - never(repeating).execute(); - never(oneoff).execute(); - }}); - timer.tick(10 * 1000); + + verify(oneoff, never()).execute(); + verify(repeating, never()).execute(); } public void testScheduleWillExecuteImmediatelyOnAnyTick() { timer.schedule(oneoff); - checking(new Expectations() {{ - one(oneoff).execute(); - }}); - timer.tick(0); + verify(oneoff, times(1)).execute(); } /** Tests that scheduling a task with negative start time throws an exception. */ @@ -134,14 +120,12 @@ public class FakeTimerServiceTest extends MockObjectTestCase { public void testInterval0() { timer.scheduleRepeating(repeating, 500, 0); timer.tick(499); - checking(new Expectations() {{ - exactly(5).of(repeating).execute(); - will(returnValue(true)); - one(repeating).execute(); - will(returnValue(false)); - never(repeating).execute(); - }}); + + verify(repeating, never()).execute(); + when(repeating.execute()).thenReturn(true, true, true, true, false); + timer.tick(1); + verify(repeating, times(5)).execute(); } /** @@ -153,42 +137,39 @@ public class FakeTimerServiceTest extends MockObjectTestCase { final IncrementalTask[] tasks = new IncrementalTask[taskCount]; for (int i = 0; i < taskCount; i++) { tasks[i] = mock(IncrementalTask.class, "repeating_" + i); + if (i==0) { + when(tasks[i].execute()).thenReturn(true, false); + } else { + when(tasks[i].execute()).thenReturn(false); + } timer.scheduleRepeating(tasks[i], 1, 0); } - final Sequence seq = sequence("callOrder"); - checking(new Expectations() {{ - for (IncrementalTask task : tasks) { - one(task).execute(); - will(returnValue(true)); - inSequence(seq); - } - for (IncrementalTask task : tasks) { - one(task).execute(); - will(returnValue(false)); - inSequence(seq); - never(task).execute(); - } - }}); + InOrder inOrder = inOrder((Object[]) tasks); + timer.tick(1); + + for (int i = 0; i < taskCount; i++) { + inOrder.verify(tasks[i]).execute(); + } + inOrder.verify(tasks[0]).execute(); + + verify(tasks[0], times(2)).execute(); } public void testReschedulingCancelsFirst() { timer.scheduleDelayed(oneoff, 500); - checking(new Expectations() {{ - never(oneoff).execute(); - }}); - timer.tick(499); + verify(oneoff, never()).execute(); + timer.scheduleDelayed(oneoff, 1000); - timer.tick(2); - checking(new Expectations() {{ - one(oneoff).execute(); - }}); + timer.tick(2); + verify(oneoff, never()).execute(); timer.tick(1000); + verify(oneoff, times(1)).execute(); } /** @@ -200,11 +181,10 @@ public class FakeTimerServiceTest extends MockObjectTestCase { timer.scheduleDelayed(oneoff, time); final Task anotherTask = mock(Task.class, "another_task"); timer.scheduleDelayed(anotherTask, time); - checking(new Expectations() {{ - one(oneoff).execute(); - one(anotherTask).execute(); - }}); + timer.tick(time); + verify(oneoff, times(1)).execute(); + verify(anotherTask, times(1)).execute(); } /** Tests that multiple processes can be run at the same time. */ @@ -214,19 +194,12 @@ public class FakeTimerServiceTest extends MockObjectTestCase { timer.scheduleRepeating(repeating, 0, time); timer.scheduleRepeating(anotherTask, time, time); - checking(new Expectations() {{ - one(repeating).execute(); - will(returnValue(true)); - }}); timer.tick(0); + verify(repeating, times(1)).execute(); - checking(new Expectations() {{ - one(repeating).execute(); - will(returnValue(true)); - one(anotherTask).execute(); - will(returnValue(true)); - }}); timer.tick(time); + verify(repeating, times(2)).execute(); + verify(anotherTask, times(1)).execute(); } /** @@ -235,12 +208,11 @@ public class FakeTimerServiceTest extends MockObjectTestCase { */ public void testRepeatedTaskMakesUpForMissedExecutions() { timer.scheduleRepeating(repeating, 5, 10); + timer.tick(4); - checking(new Expectations() {{ - exactly(10).of(repeating).execute(); - will(returnValue(true)); - }}); + verify(repeating, never()).execute(); timer.tick(99); + verify(repeating, times(10)).execute(); } /** @@ -249,14 +221,12 @@ public class FakeTimerServiceTest extends MockObjectTestCase { */ public void testIncrementalTaskIsCanceledIfItReturnsFalse() { timer.scheduleRepeating(repeating, 0, 1); - checking(new Expectations() {{ - exactly(10).of(repeating).execute(); - will(returnValue(true)); - one(repeating).execute(); - will(returnValue(false)); - never(repeating).execute(); - }}); - timer.tick(1000); + when(repeating.execute()).thenReturn(true, true, true, true, false); + + timer.tick(4); + verify(repeating, times(5)).execute(); + timer.tick(100); + verify(repeating, times(5)).execute(); } /** @@ -267,9 +237,7 @@ public class FakeTimerServiceTest extends MockObjectTestCase { */ public void testNormalTaskIsRunOnlyOnce() { timer.schedule(oneoff); - checking(new Expectations() {{ - one(oneoff).execute(); - }}); timer.tick(1000); + verify(oneoff, times(1)).execute(); } } http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/test/java/org/waveprotocol/wave/client/testing/UndercurrentHarness.java ---------------------------------------------------------------------- diff --git a/wave/src/test/java/org/waveprotocol/wave/client/testing/UndercurrentHarness.java b/wave/src/test/java/org/waveprotocol/wave/client/testing/UndercurrentHarness.java new file mode 100644 index 0000000..48a6753 --- /dev/null +++ b/wave/src/test/java/org/waveprotocol/wave/client/testing/UndercurrentHarness.java @@ -0,0 +1,380 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + +package org.waveprotocol.wave.client.testing; + +import com.google.gwt.core.client.Duration; +import com.google.gwt.core.client.EntryPoint; +import com.google.gwt.core.client.GWT; +import com.google.gwt.core.client.GWT.UncaughtExceptionHandler; +import com.google.gwt.core.client.Scheduler; +import com.google.gwt.core.client.Scheduler.RepeatingCommand; +import com.google.gwt.dom.client.Document; +import com.google.gwt.dom.client.Element; +import com.google.gwt.user.client.Command; + +import org.waveprotocol.wave.client.StageOne; +import org.waveprotocol.wave.client.StageThree; +import org.waveprotocol.wave.client.StageTwo; +import org.waveprotocol.wave.client.StageZero; +import org.waveprotocol.wave.client.Stages; +import org.waveprotocol.wave.client.common.safehtml.SafeHtmlBuilder; +import org.waveprotocol.wave.client.common.util.AsyncHolder; +import org.waveprotocol.wave.client.concurrencycontrol.MuxConnector; +import org.waveprotocol.wave.client.doodad.DoodadInstallers; +import org.waveprotocol.wave.client.doodad.attachment.AttachmentManagerProvider; +import org.waveprotocol.wave.client.doodad.attachment.testing.FakeAttachmentsManager; +import org.waveprotocol.wave.client.util.ClientFlags; +import org.waveprotocol.wave.client.util.NullTypedSource; +import org.waveprotocol.wave.client.util.OverridingTypedSource; +import org.waveprotocol.wave.client.wavepanel.impl.toolbar.color.ComplexColorPicker; +import org.waveprotocol.wave.client.wavepanel.impl.toolbar.color.SampleCustomColorPicker; +import org.waveprotocol.wave.common.bootstrap.FlagConstants; +import org.waveprotocol.wave.concurrencycontrol.channel.WaveViewService; +import org.waveprotocol.wave.model.conversation.Conversation; +import org.waveprotocol.wave.model.conversation.ConversationBlip; +import org.waveprotocol.wave.model.conversation.ConversationThread; +import org.waveprotocol.wave.model.conversation.ConversationView; +import org.waveprotocol.wave.model.conversation.WaveBasedConversationView; +import org.waveprotocol.wave.model.document.util.XmlStringBuilder; +import org.waveprotocol.wave.model.id.IdGenerator; +import org.waveprotocol.wave.model.schema.SchemaProvider; +import org.waveprotocol.wave.model.schema.conversation.ConversationSchemas; +import org.waveprotocol.wave.model.testing.BasicFactories; +import org.waveprotocol.wave.model.testing.FakeIdGenerator; +import org.waveprotocol.wave.model.util.CollectionUtils; +import org.waveprotocol.wave.model.util.ReadableStringMap.ProcV; +import org.waveprotocol.wave.model.util.StringMap; +import org.waveprotocol.wave.model.wave.ParticipantId; +import org.waveprotocol.wave.model.wave.data.DocumentFactory; +import org.waveprotocol.wave.model.wave.data.ObservableWaveletData; +import org.waveprotocol.wave.model.wave.data.ReadableWaveletData; +import org.waveprotocol.wave.model.wave.data.WaveViewData; +import org.waveprotocol.wave.model.wave.data.impl.WaveViewDataImpl; +import org.waveprotocol.wave.model.wave.data.impl.WaveletDataImpl; +import org.waveprotocol.wave.model.wave.opbased.OpBasedWavelet; +import org.waveprotocol.wave.model.wave.opbased.WaveViewImpl; +import org.waveprotocol.wave.model.wave.opbased.WaveViewImpl.WaveletConfigurator; +import org.waveprotocol.wave.model.wave.opbased.WaveViewImpl.WaveletFactory; + +/** + * Kicks off some initial actions for development purposes. + * + */ +public class UndercurrentHarness implements EntryPoint { + + private UndercurrentHarness() { + } + + private static boolean loaded; + + /** + * Runs the harness script. + */ + @Override + public void onModuleLoad() { + AttachmentManagerProvider.init(new FakeAttachmentsManager()); + if (loaded) { + return; + } + loaded = true; + + final Timeline timeline = new Timeline(); + new Stages() { + + @Override + protected AsyncHolder<StageZero> createStageZeroLoader() { + return new StageZero.DefaultProvider() { + + @Override + protected void onStageInit() { + timeline.add("stage0_start"); + } + + @Override + protected void onStageLoaded() { + timeline.add("stage0_end"); + } + + @Override + protected UncaughtExceptionHandler createUncaughtExceptionHandler() { + return GWT.getUncaughtExceptionHandler(); + } + }; + } + + @Override + protected AsyncHolder<StageOne> createStageOneLoader(StageZero zero) { + return new StageOne.DefaultProvider(zero) { + @Override + protected void onStageInit() { + timeline.add("stage1_start"); + } + + @Override + protected void onStageLoaded() { + timeline.add("stage1_end"); + } + + @Override + protected Element createWaveHolder() { + return Document.get().getElementById("initialHtml"); + } + }; + } + + @Override + protected AsyncHolder<StageTwo> createStageTwoLoader(StageOne one) { + return new StageTwo.DefaultProvider(one, null) { + + @Override + protected void onStageInit() { + timeline.add("stage2_start"); + } + + @Override + protected void onStageLoaded() { + timeline.add("stage2_end"); + } + + @Override + protected void fetchWave(Accessor<WaveViewData> whenReady) { + timeline.add("fakewave_start"); + WaveViewData fake = WaveFactory.create(getDocumentRegistry()); + timeline.add("fakewave_end"); + whenReady.use(fake); + } + + @Override + protected ParticipantId createSignedInUser() { + return ParticipantId.ofUnsafe("nob...@example.com"); + } + + @Override + protected String createSessionId() { + return "session"; + } + + @Override + protected MuxConnector createConnector() { + return new MuxConnector() { + @Override + public void connect(Command whenOpened) { + if (whenOpened != null) { + whenOpened.execute(); + } + } + + @Override + public void close() { + // Ignore + } + }; + } + + @Override + protected WaveViewService createWaveViewService() { + // The vacuous MuxConnector should avoid the need for a + // communication layer. + throw new UnsupportedOperationException(); + } + + @Override + protected SchemaProvider createSchemas() { + return new ConversationSchemas(); + } + }; + } + + @Override + protected AsyncHolder<StageThree> createStageThreeLoader(StageTwo two) { + ClientFlags.resetWithSourceForTesting(OverridingTypedSource.of(new NullTypedSource()) + .withBoolean(FlagConstants.ENABLE_UNDERCURRENT_EDITING, true) + .build()); + + // Only for test additional color pickers + new SampleCustomColorPicker(ComplexColorPicker.getInstance()); + + return new StageThree.DefaultProvider(two) { + @Override + protected void onStageInit() { + timeline.add("stage3_start"); + } + + @Override + protected void onStageLoaded() { + timeline.add("stage3_end"); + } + }; + } + }.load(new Command() { + @Override + public void execute() { + showInfo(timeline); + } + }); + } + + /** + * Populates the info box. Continuously reports which element has browser + * focus, and reports timing information for the stage loading. + * + * @param timeline timeline to report + */ + private static void showInfo(Timeline timeline) { + Element timeBox = Document.get().getElementById("timeline"); + timeline.dump(timeBox); + + Scheduler.get().scheduleFixedDelay(new RepeatingCommand() { + private final Element activeBox = Document.get().getElementById("active"); + + @Override + public boolean execute() { + Element e = getActiveElement(); + String text = (e != null ? e.getTagName() + " id:" + e.getId() : "none"); + activeBox.setInnerText(text); + return true; + } + + private native Element getActiveElement() /*-{ + return $doc.activeElement; + }-*/; + }, 1000); + } + + /** + * Creates a sample wave with a conversation in it. + */ + private final static class WaveFactory { + + /** + * Creates a sample wave. + * + * @param docFactory factory/registry for documents in the wave + * @return the wave state of the sample wave. + */ + public static WaveViewDataImpl create(DocumentFactory<?> docFactory) { + // Create a sample wave. + WaveViewData sampleData = createSampleWave(); + + // Now build one that has the same setup state as that required by + // undercurrent (complex issue with the per-document output sinks). + WaveViewDataImpl newData = WaveViewDataImpl.create(sampleData.getWaveId()); + WaveletDataImpl.Factory copier = WaveletDataImpl.Factory.create(docFactory); + for (ReadableWaveletData src : sampleData.getWavelets()) { + WaveletDataImpl copied = copier.create(src); + for (ParticipantId p : src.getParticipants()) { + copied.addParticipant(p); + } + copied.setVersion(copied.getVersion()); + copied.setHashedVersion(src.getHashedVersion()); + copied.setLastModifiedTime(src.getLastModifiedTime()); + newData.addWavelet(copied); + } + return newData; + } + + /** @return a sample wave with a conversation in it. */ + private static WaveViewData createSampleWave() { + final ParticipantId sampleAuthor = ParticipantId.ofUnsafe("nob...@example.com"); + IdGenerator gen = FakeIdGenerator.create(); + final WaveViewDataImpl waveData = WaveViewDataImpl.create(gen.newWaveId()); + final DocumentFactory<?> docFactory = BasicFactories.fakeDocumentFactory(); + final ObservableWaveletData.Factory<?> waveletDataFactory = + new ObservableWaveletData.Factory<WaveletDataImpl>() { + private final ObservableWaveletData.Factory<WaveletDataImpl> inner = + WaveletDataImpl.Factory.create(docFactory); + + @Override + public WaveletDataImpl create(ReadableWaveletData data) { + WaveletDataImpl wavelet = inner.create(data); + waveData.addWavelet(wavelet); + return wavelet; + } + }; + WaveletFactory<OpBasedWavelet> waveletFactory = BasicFactories + .opBasedWaveletFactoryBuilder() + .with(waveletDataFactory) + .with(sampleAuthor) + .build(); + + WaveViewImpl<?> wave = WaveViewImpl.create( + waveletFactory, waveData.getWaveId(), gen, sampleAuthor, WaveletConfigurator.ADD_CREATOR); + + // Build a conversation in that wave. + ConversationView v = WaveBasedConversationView.create(wave, gen); + Conversation c = v.createRoot(); + ConversationThread root = c.getRootThread(); + sampleReply(root.appendBlip()); + write(root.appendBlip()); + write(root.appendBlip()); + write(root.appendBlip()); + + return waveData; + } + + private static void write(ConversationBlip blip) { + org.waveprotocol.wave.model.document.Document d = blip.getContent(); + d.emptyElement(d.getDocumentElement()); + d.appendXml(XmlStringBuilder.createFromXmlString("<body><line></line>Hello World</body>")); + } + + private static void sampleReply(ConversationBlip blip) { + write(blip); + ConversationThread thread = blip.addReplyThread(8); + write(thread.appendBlip()); + } + + private static void biggerSampleReply(ConversationBlip blip) { + write(blip); + ConversationThread thread = blip.addReplyThread(); + sampleReply(thread.appendBlip()); + sampleReply(thread.appendBlip()); + write(thread.appendBlip()); + } + } + + private static class Timeline { + private final StringMap<Integer> events = CollectionUtils.createStringMap(); + private final Duration duration = new Duration(); + + void add(String name) { + events.put(name, duration.elapsedMillis()); + } + + void dump(Element timeBox) { + final SafeHtmlBuilder timeHtml = new SafeHtmlBuilder(); + timeHtml.appendHtmlConstant("<table cellpadding='0' cellspacing='0'>"); + events.each(new ProcV<Integer>() { + @Override + public void apply(String key, Integer value) { + timeHtml.appendHtmlConstant("<tr><td>"); + timeHtml.appendEscaped(key); + timeHtml.appendHtmlConstant(":</td><td>"); + timeHtml.appendEscaped("" + value); + timeHtml.appendHtmlConstant("</td></tr>"); + } + }); + timeHtml.appendHtmlConstant("</table>"); + timeBox.setInnerHTML(timeHtml.toSafeHtml().asString()); + + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/test/java/org/waveprotocol/wave/client/testing/public/UndercurrentHarness.html ---------------------------------------------------------------------- diff --git a/wave/src/test/java/org/waveprotocol/wave/client/testing/public/UndercurrentHarness.html b/wave/src/test/java/org/waveprotocol/wave/client/testing/public/UndercurrentHarness.html new file mode 100644 index 0000000..a7ac1a3 --- /dev/null +++ b/wave/src/test/java/org/waveprotocol/wave/client/testing/public/UndercurrentHarness.html @@ -0,0 +1,86 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<html> + <head> + <meta http-equiv="Content-type" content="text/html;charset=UTF-8"> + <meta name="gwt:property" content="locale=en"> + <title>Undercurrent Harness</title> + <style type='text/css'> + /* Full screen box. */ + body { + position: absolute; + margin: 0; + padding: 0; + left: 0; + right: 0; + top: 0; + bottom: 0; + + /* + * Arial seems to be the only non-ugly sans-serif font that renders roughly the same on both + * Chrome and Firefox. e.g., 'sans-serif' on Firefox is a nicer mystery font, because it is + * wider, but Chrome binds 'sans-serif' to 'arial'. + */ + font-family: arial; + font-size: small; + } + + /* Fixed-width and horizontally centered, in a way that works on IE. */ + #initialHtml { + position: absolute; + left: 50%; + right: 50%; + top: 4em; /* Enough space for the header. */ + bottom: 4em; + /* Expand out of the center line, aiming for ~70-75 character blip widths. */ + margin-left: -250px; + margin-right: -250px; + border: 1px solid lightGray; + } + + #info { + position: absolute; + z-index: 100; + right: 20px; + top: 20px; + padding: 0.2em; + width: 10em; + border: 1px solid black; + background-color: lightGray; + } + + #timeline { + margin-left: 1em; + } + + </style> + </head> + <body> + <h2>Undercurrent Test Harness</h2> + <div id='initialHtml'></div> + <div id='info'> + Active: <span id='active'></span><br/> + Timing: + <div id='timeline'></div> + </div> + <script type='text/javascript' src='waveharness.nocache.js'> + </script> + </body> +</html> http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/test/java/org/waveprotocol/wave/client/wavepanel/tests.gwt.xml ---------------------------------------------------------------------- diff --git a/wave/src/test/java/org/waveprotocol/wave/client/wavepanel/tests.gwt.xml b/wave/src/test/java/org/waveprotocol/wave/client/wavepanel/tests.gwt.xml index 866f890..a69575b 100644 --- a/wave/src/test/java/org/waveprotocol/wave/client/wavepanel/tests.gwt.xml +++ b/wave/src/test/java/org/waveprotocol/wave/client/wavepanel/tests.gwt.xml @@ -22,7 +22,13 @@ <module> <inherits name="com.google.gwt.user.User"/> - + <inherits name="org.waveprotocol.wave.model.util.Util"/> + <inherits name="org.waveprotocol.wave.client.common.safehtml.SafeHtml"/> + <inherits name="org.waveprotocol.wave.client.common.util.Util"/> + <inherits name="org.waveprotocol.wave.client.uibuilder.UiBuilder"/> + <inherits name="org.waveprotocol.wave.client.uibuilder.UiBuilder"/> + <inherits name="org.waveprotocol.box.stat.Stat"/> + <source path=""/> </module> http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/d35211be/wave/src/test/java/org/waveprotocol/wave/model/conversation/testing/BlipTestUtils.java ---------------------------------------------------------------------- diff --git a/wave/src/test/java/org/waveprotocol/wave/model/conversation/testing/BlipTestUtils.java b/wave/src/test/java/org/waveprotocol/wave/model/conversation/testing/BlipTestUtils.java new file mode 100644 index 0000000..4bdf453 --- /dev/null +++ b/wave/src/test/java/org/waveprotocol/wave/model/conversation/testing/BlipTestUtils.java @@ -0,0 +1,94 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.waveprotocol.wave.model.conversation.testing; + +import org.waveprotocol.wave.model.conversation.Blips; +import org.waveprotocol.wave.model.conversation.ConversationBlip; +import org.waveprotocol.wave.model.conversation.TitleHelper; + +import org.waveprotocol.wave.model.document.ReadableWDocument; +import org.waveprotocol.wave.model.document.indexed.IndexedDocument; +import org.waveprotocol.wave.model.document.operation.automaton.DocumentSchema; +import org.waveprotocol.wave.model.document.raw.impl.Element; +import org.waveprotocol.wave.model.document.raw.impl.Node; +import org.waveprotocol.wave.model.document.raw.impl.Text; +import org.waveprotocol.wave.model.document.util.DocHelper; +import org.waveprotocol.wave.model.document.util.DocProviders; +import org.waveprotocol.wave.model.document.util.LineContainers; +import org.waveprotocol.wave.model.document.util.XmlStringBuilder; + +/** + * Utility functions used by conversation tests. + * + */ +public final class BlipTestUtils { + + // Non-instantiatable class + private BlipTestUtils() { + } + + /** + * Returns the position of the body element in an initial, empty, blip. + */ + public static int getInitialBlipBodyPosition() { + IndexedDocument<Node, Element, Text> d = DocProviders.POJO.build( + TitleHelper.emptyDocumentWithTitle(), + DocumentSchema.NO_SCHEMA_CONSTRAINTS); + return getBodyPosition(d); + } + + + /** + * Returns the position of the body element of the given blip. + */ + public static int getBodyPosition(ConversationBlip blip) { + return getBodyPosition(blip.getContent()); + } + + /** + * Returns the position of the body element of the given document or 0 if the + * document has no body. + */ + public static <N, E extends N> int getBodyPosition(ReadableWDocument<N, E, ?> doc) { + N body = DocHelper.getElementWithTagName(doc, Blips.BODY_TAGNAME); + if (body == null) return 0; + return doc.getLocation(body); + } + + /** + * Wrap the given xml string containing a blip body in an XmlStringBuilder + * and prepend an empty head. + */ + public static XmlStringBuilder prependHead(String body) { + return XmlStringBuilder.createEmpty() + .append(Blips.INITIAL_HEAD) + .append(XmlStringBuilder.createFromXmlString(body)); + } + + /** + * Returns a blip whose contents are the given lines. + */ + public static String debugBlipWrap(String ... lines) { + return XmlStringBuilder.createEmpty() + .append(Blips.INITIAL_HEAD) + .append(XmlStringBuilder.createFromXmlString(LineContainers.debugContainerWrap(lines))) + .toString(); + } +}