/** * Copyright 2009 Google Inc. * * Licensed 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.concurrencycontrol.client; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.assertNull; import org.waveprotocol.wave.concurrencycontrol.common.DeltaPair; import org.waveprotocol.wave.model.operation.wave.WaveletOperation; import org.waveprotocol.wave.model.util.CollectionUtils; import java.util.Arrays; import java.util.Collections; import java.util.LinkedList; import java.util.List; /** * Mock for describing interactions with a {@link OperationQueue.Transformer}, * including specifying what deltas should result from those interactions. * */ class MockDeltaTransformer implements OperationQueue.Transformer { /** Representation of an expected call to {@link #transform()}. */ static class Expectation { private final WaveletOperation[] inputClientOps; private List<WaveletOperation> outputClientDelta; private final List<WaveletOperation> outputServerDelta; /** * Sets up an expected transform that will accept an input client delta * which has the given op list. It will accept any input server delta and * output its own server delta. */ Expectation(WaveletOperation... inputClientOps) { this.inputClientOps = inputClientOps; this.outputServerDelta = new MergingSequence(); } /** * Asserts that the given delta meets the requirements to be the input * client delta for this expectation. */ void assertClientInputValid(Iterable<WaveletOperation> candidate) { assertEquals(Arrays.asList(inputClientOps), CollectionUtils.newArrayList(candidate)); } /** * Specifies that the output client delta should be the same as the input * client delta. */ public void echo() { transformTo(inputClientOps); } /** * Gets the client/server delta pair that will be output by an appropriately * timed and parameterised call to this expected transform. */ DeltaPair getOutput() { assertNotNull("No output client delta specified", outputClientDelta); return new DeltaPair(outputClientDelta, outputServerDelta); } public void kill() { transformTo(); } /** * Specifies that the output client delta should consist of the given * operations. */ public void transformTo(WaveletOperation... outputClientOps) { assertNull("Output client delta already specified", outputClientDelta); outputClientDelta = new MergingSequence(Arrays.asList(outputClientOps)); } } private final LinkedList<Expectation> expectations; private final List<WaveletOperation> firstServerInputDelta; /** * Creates a transformer that initially has no expectations, and only allows * calls to {@link #transform()} that have been expected via * {@link #expect(WaveletOperation...)}. */ public MockDeltaTransformer() { expectations = CollectionUtils.newLinkedList(); firstServerInputDelta = new MergingSequence(); } /** Checks that all expected calls to transform have been made. */ public void checkDone() { assertEquals(Collections.emptyList(), expectations); } /** * Sets up that the transform call after all existing expectations must be one * with a client input delta consisting of the given ops. * * @return the expectation which should be set to either * {@link Expectation#echo()} the client input delta or return some * transformed delta using * {@link Expectation#transformTo(WaveletOperation...)}. */ public Expectation expect(WaveletOperation... ops) { Expectation expectation = new Expectation(ops); expectations.addLast(expectation); return expectation; } /** * Gets the ops that should be given to the first * {@link #transform()} call. */ public List<WaveletOperation> getInputServerDelta() { return firstServerInputDelta; } /** * Gets the delta that should be produced if all expected transforms are * performed in order on the {@link #getInputServerDelta()}. */ public List<WaveletOperation> getOutputServerDelta() { List<WaveletOperation> delta; if (expectations.isEmpty()) { delta = firstServerInputDelta; } else { delta = expectations.getLast().getOutput().getServer(); } return delta; } @Override public DeltaPair transform(Iterable<WaveletOperation> client, Iterable<WaveletOperation> server) { Expectation expectation = expectations.removeFirst(); expectation.assertClientInputValid(client); DeltaPair result = expectation.getOutput(); return result; } }