/**
* Copyright 2010 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.model.document.operation;
import junit.framework.TestCase;
import org.waveprotocol.wave.model.document.operation.impl.AttributesImpl;
import org.waveprotocol.wave.model.document.operation.impl.DocInitializationBuilder;
/**
* @author ohler@google.com (Christian Ohler)
*/
public class DocumentCostFunctionTest extends TestCase {
private static final String S0 = "";
private static final String S1A = "a";
private static final String S1B = "\uD800\uDC00"; // a surrogate pair
private static final String S2 = S1B + S1A;
private static final String S10 = " 12345678*";
// These constants have X_Y suffixes where X is the number of times the object
// overhead is incurred, and Y is the total number of code points in strings.
private static final Attributes ATTR0_0 = new AttributesImpl();
private static final Attributes ATTR1_1 = new AttributesImpl(S1B, S0);
private static final Attributes ATTR1_2A = new AttributesImpl(S1A, S1A);
private static final Attributes ATTR1_2B = new AttributesImpl(S2, S0);
private static final Attributes ATTR2_2 = new AttributesImpl(S1A, S0, S1B, S0);
private static final Attributes ATTR2_3 = new AttributesImpl(S1A, S1B, S1B, S0);
private static final Attributes ATTR2_12 = new AttributesImpl(S1A, S0, S1B, S10);
private static final AnnotationBoundaryMap ANN0_0 = new AnnotationBoundaryMapBuilder().build();
private static final AnnotationBoundaryMap ANN1_0A = new AnnotationBoundaryMapBuilder()
.change(S0, S0, S0).build();
private static final AnnotationBoundaryMap ANN1_0B = new AnnotationBoundaryMapBuilder()
.end(S0).build();
private static final AnnotationBoundaryMap ANN2_1 = new AnnotationBoundaryMapBuilder()
.change(S0, null, S0).end(S1A).build();
private static final AnnotationBoundaryMap ANN2_3 = new AnnotationBoundaryMapBuilder()
.end(S1B).end(S2).build();
private static final AnnotationBoundaryMap ANN2_13 = new AnnotationBoundaryMapBuilder()
.change(S10, null, S0).change(S2, null, S1B).build();
private final DocumentCostFunction f0 = DocumentCostFunction.withObjectOverhead(0);
private final DocumentCostFunction f1 = DocumentCostFunction.withObjectOverhead(1);
private final DocumentCostFunction f2 = DocumentCostFunction.withObjectOverhead(2);
private final DocumentCostFunction f12 = DocumentCostFunction.withObjectOverhead(12);
public void testComputeStringCost() {
assertEquals(0, f1.computeCost(S0));
assertEquals(1, f1.computeCost(S1A));
assertEquals(1, f1.computeCost(S1B));
assertEquals(2, f1.computeCost(S2));
assertEquals(10, f1.computeCost(S10));
}
public void testComputeAttributesCost() {
assertEquals( 0, f0.computeCost(ATTR0_0));
assertEquals( 1, f0.computeCost(ATTR1_1));
assertEquals( 2, f0.computeCost(ATTR1_2A));
assertEquals( 2, f0.computeCost(ATTR1_2B));
assertEquals( 2, f0.computeCost(ATTR2_2));
assertEquals( 3, f0.computeCost(ATTR2_3));
assertEquals(12, f0.computeCost(ATTR2_12));
assertEquals( 0, f1.computeCost(ATTR0_0));
assertEquals( 2, f1.computeCost(ATTR1_1));
assertEquals( 3, f1.computeCost(ATTR1_2A));
assertEquals( 3, f1.computeCost(ATTR1_2B));
assertEquals( 4, f1.computeCost(ATTR2_2));
assertEquals( 5, f1.computeCost(ATTR2_3));
assertEquals(14, f1.computeCost(ATTR2_12));
assertEquals( 0, f2.computeCost(ATTR0_0));
assertEquals( 3, f2.computeCost(ATTR1_1));
assertEquals( 4, f2.computeCost(ATTR1_2A));
assertEquals( 4, f2.computeCost(ATTR1_2B));
assertEquals( 6, f2.computeCost(ATTR2_2));
assertEquals( 7, f2.computeCost(ATTR2_3));
assertEquals(16, f2.computeCost(ATTR2_12));
assertEquals( 0, f12.computeCost(ATTR0_0));
assertEquals(13, f12.computeCost(ATTR1_1));
assertEquals(14, f12.computeCost(ATTR1_2A));
assertEquals(14, f12.computeCost(ATTR1_2B));
assertEquals(26, f12.computeCost(ATTR2_2));
assertEquals(27, f12.computeCost(ATTR2_3));
assertEquals(36, f12.computeCost(ATTR2_12));
}
public void testComputeAnnotationBoundaryMapCost() {
assertEquals( 0, f0.computeCost(ANN0_0));
assertEquals( 0, f0.computeCost(ANN1_0A));
assertEquals( 0, f0.computeCost(ANN1_0B));
assertEquals( 1, f0.computeCost(ANN2_1));
assertEquals( 3, f0.computeCost(ANN2_3));
assertEquals(13, f0.computeCost(ANN2_13));
assertEquals( 0, f1.computeCost(ANN0_0));
assertEquals( 1, f1.computeCost(ANN1_0A));
assertEquals( 1, f1.computeCost(ANN1_0B));
assertEquals( 3, f1.computeCost(ANN2_1));
assertEquals( 5, f1.computeCost(ANN2_3));
assertEquals(15, f1.computeCost(ANN2_13));
assertEquals( 0, f2.computeCost(ANN0_0));
assertEquals( 2, f2.computeCost(ANN1_0A));
assertEquals( 2, f2.computeCost(ANN1_0B));
assertEquals( 5, f2.computeCost(ANN2_1));
assertEquals( 7, f2.computeCost(ANN2_3));
assertEquals(17, f2.computeCost(ANN2_13));
assertEquals( 0, f12.computeCost(ANN0_0));
assertEquals(12, f12.computeCost(ANN1_0A));
assertEquals(12, f12.computeCost(ANN1_0B));
assertEquals(25, f12.computeCost(ANN2_1));
assertEquals(27, f12.computeCost(ANN2_3));
assertEquals(37, f12.computeCost(ANN2_13));
}
private static final DocInitialization DOC0_0 = new DocInitializationBuilder().build();
private static final DocInitialization DOC1_0 = new DocInitializationBuilder()
.annotationBoundary(ANN0_0).build();
private static final DocInitialization DOC1_2 = new DocInitializationBuilder()
.characters(S1A + S1A).build();
private static final DocInitialization DOC2_2 = new DocInitializationBuilder().characters(S1A).
characters(S1A).build();
private static final DocInitialization DOC3_2 = new DocInitializationBuilder()
.elementStart(S1B, ATTR1_1).elementEnd().build();
private static final DocInitialization DOC4_14 = new DocInitializationBuilder()
.elementStart(S2, ATTR2_12).elementEnd().build();
private static final DocInitialization DOC5_15 = new DocInitializationBuilder()
.elementStart(S2, ATTR2_12).characters(S1A).elementEnd().build();
private static final DocInitialization DOC6_15 = new DocInitializationBuilder()
.annotationBoundary(ANN0_0).elementStart(S2, ATTR2_12).characters(S1A).elementEnd().build();
private static final DocInitialization DOC7_15 = new DocInitializationBuilder()
.annotationBoundary(ANN0_0).elementStart(S2, ATTR2_12).annotationBoundary(ANN0_0)
.characters(S1A).elementEnd().build();
private static final DocInitialization DOC9_15 = new DocInitializationBuilder()
.annotationBoundary(ANN1_0A).elementStart(S2, ATTR2_12).annotationBoundary(ANN1_0B)
.characters(S1A).elementEnd().build();
private static final DocInitialization DOC12_17 = new DocInitializationBuilder()
.annotationBoundary(ANN1_0A).elementStart(S2, ATTR2_12).annotationBoundary(ANN1_0B)
.characters(S1A).elementStart(S1A, ATTR1_1).elementEnd().elementEnd().build();
public void testComputeDocumentCost() {
// Empty document has a cost of zero. This is important as, conceptually,
// documents with all possible names exist but are initially empty.
assertEquals(0, f0.computeCost(DOC0_0));
assertEquals(0, f1.computeCost(DOC0_0));
assertEquals(0, f2.computeCost(DOC0_0));
assertEquals(0, f12.computeCost(DOC0_0));
// Non-normalized documents are more expensive than normalized ones.
assertEquals(0, f0.computeCost(DOC1_0));
assertEquals(2, f0.computeCost(DOC1_2));
assertEquals(2, f0.computeCost(DOC2_2));
assertEquals(1, f1.computeCost(DOC1_0));
assertEquals(3, f1.computeCost(DOC1_2));
assertEquals(4, f1.computeCost(DOC2_2));
assertEquals(2, f2.computeCost(DOC1_0));
assertEquals(4, f2.computeCost(DOC1_2));
assertEquals(6, f2.computeCost(DOC2_2));
assertEquals(12, f12.computeCost(DOC1_0));
assertEquals(14, f12.computeCost(DOC1_2));
assertEquals(26, f12.computeCost(DOC2_2));
// Some bigger ops.
assertEquals( 2, f0.computeCost(DOC3_2));
assertEquals(14, f0.computeCost(DOC4_14));
assertEquals(15, f0.computeCost(DOC5_15));
assertEquals(15, f0.computeCost(DOC6_15));
assertEquals(15, f0.computeCost(DOC7_15));
assertEquals(15, f0.computeCost(DOC9_15));
assertEquals(17, f0.computeCost(DOC12_17));
assertEquals( 5, f1.computeCost(DOC3_2));
assertEquals(18, f1.computeCost(DOC4_14));
assertEquals(20, f1.computeCost(DOC5_15));
assertEquals(21, f1.computeCost(DOC6_15));
assertEquals(22, f1.computeCost(DOC7_15));
assertEquals(24, f1.computeCost(DOC9_15));
assertEquals(29, f1.computeCost(DOC12_17));
assertEquals(2 * 3 + 2, f2.computeCost(DOC3_2));
assertEquals(2 * 4 + 14, f2.computeCost(DOC4_14));
assertEquals(2 * 5 + 15, f2.computeCost(DOC5_15));
assertEquals(2 * 6 + 15, f2.computeCost(DOC6_15));
assertEquals(2 * 7 + 15, f2.computeCost(DOC7_15));
assertEquals(2 * 9 + 15, f2.computeCost(DOC9_15));
assertEquals(2 * 12 + 17, f2.computeCost(DOC12_17));
assertEquals(12 * 3 + 2, f12.computeCost(DOC3_2));
assertEquals(12 * 4 + 14, f12.computeCost(DOC4_14));
assertEquals(12 * 5 + 15, f12.computeCost(DOC5_15));
assertEquals(12 * 6 + 15, f12.computeCost(DOC6_15));
assertEquals(12 * 7 + 15, f12.computeCost(DOC7_15));
assertEquals(12 * 9 + 15, f12.computeCost(DOC9_15));
assertEquals(12 * 12 + 17, f12.computeCost(DOC12_17));
}
}