/* * Copyright 2017 ThoughtWorks, 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 com.thoughtworks.go.plugin.access.configrepo.contract; import com.google.gson.*; import com.google.gson.reflect.TypeToken; import com.thoughtworks.go.plugin.access.configrepo.ErrorCollection; import com.thoughtworks.go.plugin.access.configrepo.codec.GsonCodec; import org.junit.Before; import org.junit.Test; import java.lang.reflect.Type; import java.util.HashMap; import java.util.Map; import static junit.framework.TestCase.assertNotNull; import static junit.framework.TestCase.fail; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.Is.is; public abstract class CRBaseTest<T extends CRBase> { private boolean printExamples = false; protected Gson gson; @Before public void SetUp() { GsonBuilder builder = new GsonBuilder(); if(printExamples) builder.setPrettyPrinting(); GsonCodec codec = new GsonCodec(builder); gson = codec.getGson(); } public abstract void addGoodExamples(Map<String, T> examples); public abstract void addBadExamples(Map<String, T> examples); /** * Gets collection of example instances. Key is name of example to identify it during tests. */ public Map<String,T> getExamples() { Map<String, T> examples = new HashMap<>(); this.addGoodExamples(examples); this.addBadExamples(examples); return examples; } /** * Gets collection of good example instances. Key is name of example to identify it during tests. */ public Map<String,T> getGoodExamples() { Map<String, T> examples = new HashMap<>(); this.addGoodExamples(examples); return examples; } /** * Gets collection of bad example instances. Key is name of example to identify it during tests. */ public Map<String,T> getBadExamples() { Map<String, T> examples = new HashMap<>(); this.addBadExamples(examples); return examples; } @Test public void shouldHaveEqualsImplementedForTests() { //just try equality of each example with other for(Object o : getExamples().entrySet()) { Map.Entry<String, T> right = (Map.Entry<String, T>) o; for (Map.Entry<String, T> left : getExamples().entrySet()) { if (left.getValue() == right.getValue()) assertThat(String.format("example '%s' should equal to itself", left.getKey()), left.getValue().equals(right.getValue()), is(true)); else assertThat(String.format("example '%s' should not equal to '%s'", left.getKey(), right.getKey()), left.getValue().equals(right.getValue()), is(false)); } } } @Test public void shouldSerializeToJson() { Map<String,T> examples = getExamples(); for(Map.Entry<String,T> example : examples.entrySet()) { String exampleName = example.getKey(); T value = example.getValue(); String json = gson.toJson(value); if(printExamples) { System.out.print("-----\n"); System.out.print(String.format("Example '%s':\n", exampleName)); System.out.print(json); System.out.print("\n"); } } } @Test public void shouldReturnLocation() { Map<String,T> examples = getExamples(); for(Map.Entry<String,T> example : examples.entrySet()) { String exampleName = example.getKey(); T value = example.getValue(); String location = value.getLocation("TEST_PARENT"); if(printExamples) { System.out.print("-----\n"); System.out.print(String.format("Example '%s' Location:\n", exampleName)); System.out.print(location); } assertNotNull(location); } } @Test public void shouldIgnoreWhenJsonHasUnknownElements() { Map<String,T> examples = getExamples(); for(Map.Entry<String,T> example : examples.entrySet()) { T value = example.getValue(); JsonObject jsonObject = (JsonObject)gson.toJsonTree(value); jsonObject.add("extraProperty", new JsonPrimitive("This is not part of message type")); String json = gson.toJson(jsonObject); T deserializedValue = (T)gson.fromJson(json,value.getClass()); assertThat(String.format("Example %s - Deserialized value should equal to value before serialization", example.getKey()), deserializedValue, is(value)); } } @Test public void shouldSerializeToJsonAndDeserialize() { Map<String,T> examples = getExamples(); for(Map.Entry<String,T> example : examples.entrySet()) { T value = example.getValue(); String json = gson.toJson(value); Type typeOfT = new TypeToken<T>(){}.getType(); T deserializedValue = (T)gson.fromJson(json,value.getClass()); assertThat(String.format("Example %s - Deserialized value should equal to value before serialization",example.getKey()), deserializedValue,is(value)); } } @Test public void shouldGetErrorsWhenDeserializedFromEmptyBlock() { String json = "{}"; Class<? extends CRBase> typeOfT = null; for(T example : getGoodExamples().values()) { typeOfT = example.getClass(); break; } T deserializedValue = (T)gson.fromJson(json,typeOfT); ErrorCollection errorCollection = new ErrorCollection(); deserializedValue.getErrors(errorCollection,"GetErrorsWhenDeserializedFromEmptyBlockTest"); } @Test public void shouldThrowWhenJsonFormatIsInvalid() { Map<String,T> examples = getExamples(); for(Map.Entry<String,T> example : examples.entrySet()) { T value = example.getValue(); String json = gson.toJson(value); json += "some extra non-json content"; try { gson.fromJson(json, value.getClass()); } catch (Exception ex) { return; } fail("Should have thrown invalid format for " + example.getKey()); } } @Test public void shouldErrorWhenBadExample(){ Map<String,T> examples = getBadExamples(); for(Map.Entry<String,T> example : examples.entrySet()) { ErrorCollection errorCollection = new ErrorCollection(); example.getValue().getErrors(errorCollection,"ErrorWhenBadExampleTest"); assertThat(String.format("Example %s - invalid value should return errors",example.getKey()), errorCollection.isEmpty(),is(false)); } } @Test public void shouldNotErrorWhenGoodExample(){ Map<String,T> examples = getGoodExamples(); for(Map.Entry<String,T> example : examples.entrySet()) { ErrorCollection errorCollection = new ErrorCollection(); example.getValue().getErrors(errorCollection,"NotErrorWhenGoodExampleTest"); assertThat(String.format("Example %s - valid value should not return errors",example.getKey()), errorCollection.isEmpty(),is(true)); } } }