/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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.elasticsearch.test;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
public abstract class AbstractSerializingTestCase<T extends ToXContent & Writeable> extends AbstractWireSerializingTestCase<T> {
/**
* Generic test that creates new instance from the test instance and checks
* both for equality and asserts equality on the two instances.
*/
public void testFromXContent() throws IOException {
for (int runs = 0; runs < NUMBER_OF_TEST_RUNS; runs++) {
T testInstance = createTestInstance();
XContentType xContentType = randomFrom(XContentType.values());
XContentBuilder builder = toXContent(testInstance, xContentType);
XContentBuilder shuffled = shuffleXContent(builder);
assertParsedInstance(xContentType, shuffled.bytes(), testInstance);
for (Map.Entry<String, T> alternateVersion : getAlternateVersions().entrySet()) {
String instanceAsString = alternateVersion.getKey();
assertParsedInstance(XContentType.JSON, new BytesArray(instanceAsString), alternateVersion.getValue());
}
}
}
protected void assertParsedInstance(XContentType xContentType, BytesReference instanceAsBytes, T expectedInstance)
throws IOException {
XContentParser parser = createParser(XContentFactory.xContent(xContentType), instanceAsBytes);
T newInstance = parseInstance(parser);
assertNotSame(newInstance, expectedInstance);
assertEquals(expectedInstance, newInstance);
assertEquals(expectedInstance.hashCode(), newInstance.hashCode());
}
protected T parseInstance(XContentParser parser) throws IOException {
T parsedInstance = doParseInstance(parser);
assertNull(parser.nextToken());
return parsedInstance;
}
/**
* Parses to a new instance using the provided {@link XContentParser}
*/
protected abstract T doParseInstance(XContentParser parser) throws IOException;
/**
* Renders the provided instance in XContent
*
* @param instance
* the instance to render
* @param contentType
* the content type to render to
*/
protected XContentBuilder toXContent(T instance, XContentType contentType)
throws IOException {
XContentBuilder builder = XContentFactory.contentBuilder(contentType);
if (randomBoolean()) {
builder.prettyPrint();
}
if (instance.isFragment()) {
builder.startObject();
}
instance.toXContent(builder, ToXContent.EMPTY_PARAMS);
if (instance.isFragment()) {
builder.endObject();
}
return builder;
}
/**
* Returns alternate string representation of the instance that need to be
* tested as they are never used as output of the test instance. By default
* there are no alternate versions.
*
* These alternatives must be JSON strings.
*/
protected Map<String, T> getAlternateVersions() {
return Collections.emptyMap();
}
}