/*
* Copyright (c) 2008-2017, Hazelcast, Inc. All Rights Reserved.
*
* 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.hazelcast.query.impl.getters;
import com.hazelcast.test.HazelcastParallelClassRunner;
import com.hazelcast.test.annotation.ParallelTest;
import com.hazelcast.test.annotation.QuickTest;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.fail;
@RunWith(HazelcastParallelClassRunner.class)
@Category({QuickTest.class, ParallelTest.class})
public class MethodGetterTest {
private Method limbArrayMethod;
private Method limbCollectionMethod;
private Method nailArrayMethod;
private Method nailCollectionMethod;
private Body body;
private Nail redNail;
private Nail greenNail;
private Limb leg;
private Nail whiteNail;
private Nail blackNail;
private Limb hand;
private Limb unnamedLimb;
@Before
public void setUp() throws NoSuchMethodException {
limbArrayMethod = Body.class.getMethod("getLimbArray");
limbCollectionMethod = Body.class.getMethod("getLimbCollection");
nailArrayMethod = Limb.class.getMethod("getNailArray");
nailCollectionMethod = Limb.class.getMethod("getNailCollection");
redNail = new Nail("red");
greenNail = new Nail("green");
leg = new Limb("leg", redNail, greenNail);
whiteNail = new Nail("white");
blackNail = new Nail("black");
hand = new Limb("hand", whiteNail, blackNail);
unnamedLimb = new Limb(null);
body = new Body("bodyName", leg, hand, unnamedLimb);
}
@Test(expected = IllegalArgumentException.class)
public void constructor_whenModifierIsNotNullAndMethodReturnTypeIsNotArrayOrCollection_thenThrowIllegalArgumentException()
throws Exception {
Method method = Body.class.getMethod("getName");
new MethodGetter(null, method, "[any]", null);
}
@Test(expected = IllegalArgumentException.class)
public void constructor_whenModifierIsNegative_thenThrowIllegalArgumentException() throws Exception {
Method method = Body.class.getMethod("getName");
new MethodGetter(null, method, "[-1]", null);
}
@Test(expected = IllegalArgumentException.class)
public void constructor_whenModifierIsStarAndMethodReturnTypeIsCollection_thenThrowIllegalArgumentException() {
new MethodGetter(null, limbCollectionMethod, "[any]", null);
}
@Test(expected = IllegalArgumentException.class)
public void constructor_whenModifierIsPositionAndMethodReturnTypeIsCollection_thenThrowIllegalArgumentException() {
new MethodGetter(null, limbCollectionMethod, "[0]", null);
}
@Test
public void getValue_whenModifierOnArrayIsStar_thenReturnMultiValueResultWithAllItems() throws Exception {
MethodGetter getter = new MethodGetter(null, limbArrayMethod, "[any]", null);
MultiResult result = (MultiResult) getter.getValue(body);
assertContainsInAnyOrder(result, leg, hand, unnamedLimb);
}
@Test
public void getValue_whenParentIsMultiValueAndModifierOnArrayIsStar_thenReturnMultiValueResultWithAllItems()
throws Exception {
MethodGetter limbGetter = new MethodGetter(null, limbArrayMethod, "[any]", null);
MethodGetter nailGetter = new MethodGetter(limbGetter, nailArrayMethod, "[any]", null);
MultiResult result = (MultiResult) nailGetter.getValue(body);
assertContainsInAnyOrder(result, whiteNail, blackNail, redNail, greenNail, null);
}
@Test
public void getValue_whenParentIsMultiValueAndModifierOnArrayIsPosition_thenReturnMultiValueResultWithItemsAtPosition()
throws Exception {
MethodGetter limbGetter = new MethodGetter(null, limbArrayMethod, "[any]", null);
MethodGetter nailGetter = new MethodGetter(limbGetter, nailArrayMethod, "[0]", null);
MultiResult result = (MultiResult) nailGetter.getValue(body);
assertContainsInAnyOrder(result, redNail, whiteNail, null);
}
@Test
public void getValue_whenParentIsMultiValueAndModifierOnCollectionIsStar_thenReturnMultiValueResultWithAllItems()
throws Exception {
MethodGetter limbGetter = new MethodGetter(null, limbArrayMethod, "[any]", null);
MethodGetter nailGetter = new MethodGetter(limbGetter, nailCollectionMethod, "[any]", Nail.class);
MultiResult result = (MultiResult) nailGetter.getValue(body);
assertContainsInAnyOrder(result, whiteNail, blackNail, redNail, greenNail, null);
}
@Test
public void getValue_whenParentIsMultiValueAndModifierOnCollectionIsPosition_thenReturnMultiValueResultWithItemsAtPosition()
throws Exception {
MethodGetter limbGetter = new MethodGetter(null, limbArrayMethod, "[any]", null);
MethodGetter nailGetter = new MethodGetter(limbGetter, nailArrayMethod, "[0]", Nail.class);
MultiResult result = (MultiResult) nailGetter.getValue(body);
assertContainsInAnyOrder(result, redNail, whiteNail, null);
}
@Test
public void getValue_whenModifierOnCollectionIsStar_thenReturnMultiValueResultWithAllItems() throws Exception {
MethodGetter getter = new MethodGetter(null, limbCollectionMethod, "[any]", Limb.class);
MultiResult result = (MultiResult) getter.getValue(body);
assertContainsInAnyOrder(result, leg, hand, unnamedLimb);
}
@Test
public void getValue_whenModifierOnArrayIsPositionAndElementAtGivenPositionExist_thenReturnTheItem() throws Exception {
MethodGetter getter = new MethodGetter(null, limbArrayMethod, "[0]", null);
Limb result = (Limb) getter.getValue(body);
assertSame(leg, result);
}
@Test
public void getValue_whenModifierOnCollectionIsPositionAndElementAtGivenPositionExist_thenReturnTheItem() throws Exception {
MethodGetter getter = new MethodGetter(null, limbCollectionMethod, "[0]", Limb.class);
Limb result = (Limb) getter.getValue(body);
assertSame(leg, result);
}
@Test
public void getValue_whenModifierOnArrayIsPositionAndElementAtGivenPositionDoesNotExist_thenReturnNull() throws Exception {
MethodGetter getter = new MethodGetter(null, limbArrayMethod, "[3]", null);
Limb result = (Limb) getter.getValue(body);
assertNull(result);
}
@Test
public void getValue_whenModifierOnCollectionIsPositionAndElementAtGivenPositionDoesNotExist_thenReturnNull() throws Exception {
MethodGetter getter = new MethodGetter(null, limbCollectionMethod, "[3]", Limb.class);
Limb result = (Limb) getter.getValue(body);
assertNull(result);
}
@Test
@SuppressWarnings("unchecked")
public void getValue_whenNoModifierOnCollection_thenReturnTheCollection() throws Exception {
MethodGetter getter = new MethodGetter(null, limbCollectionMethod, null, null);
Collection<Limb> result = (Collection<Limb>) getter.getValue(body);
assertSame(body.limbCollection, result);
}
@Test
public void getValue_whenParentIsMultiResultAndNoModifier_thenReturnTheMultiResultContainingCurrentObjects()
throws Exception {
MethodGetter limbGetter = new MethodGetter(null, limbArrayMethod, "[any]", null);
Method getLimbNameMethod = Limb.class.getMethod("getName");
MethodGetter nailNameGetter = new MethodGetter(limbGetter, getLimbNameMethod, null, null);
MultiResult result = (MultiResult) nailNameGetter.getValue(body);
assertContainsInAnyOrder(result, "leg", "hand", null);
}
@Test
public void getValue_whenNoModifierOnArray_thenReturnTheArray() throws Exception {
MethodGetter getter = new MethodGetter(null, limbArrayMethod, null, null);
Limb[] result = (Limb[]) getter.getValue(body);
assertSame(body.limbArray, result);
}
@Test
public void getValue_whenInputIsNull_thenReturnNull() throws Exception {
MethodGetter getter = new MethodGetter(null, limbArrayMethod, null, null);
Limb[] result = (Limb[]) getter.getValue(null);
assertNull(result);
}
@Test
public void getReturnType_whenSetExplicitly_thenReturnIt() {
MethodGetter getter = new MethodGetter(null, limbCollectionMethod, "[any]", Limb.class);
Class returnType = getter.getReturnType();
assertEquals(Limb.class, returnType);
}
@Test
public void getReturnType_whenModifierIsPositionAndMethodReturnTypeeIsArray_thenInferReturnTypeFromTheArray() {
MethodGetter getter = new MethodGetter(null, limbArrayMethod, "[0]", null);
Class returnType = getter.getReturnType();
assertEquals(Limb.class, returnType);
}
@Test
public void getReturnType_whenModifierIsStarAndMethodReturnIsArray_thenInferReturnTypeFromTheArray() {
MethodGetter getter = new MethodGetter(null, limbArrayMethod, "[any]", null);
Class returnType = getter.getReturnType();
assertEquals(Limb.class, returnType);
}
@Test
public void getReturnType_whenNoModifierAndMethodReturnIsArray_thenReturnTheArrayType() {
MethodGetter getter = new MethodGetter(null, limbArrayMethod, null, null);
Class returnType = getter.getReturnType();
assertEquals(Limb[].class, returnType);
}
private void assertContainsInAnyOrder(MultiResult multiResult, Object... items) {
List results = multiResult.getResults();
if (results.size() != items.length) {
fail("MultiResult " + multiResult + " has size " + results.size() + ", but expected size is " + items.length);
}
for (Object item : items) {
if (!results.contains(item)) {
fail("MultiResult " + multiResult + " does not contain expected item " + item);
}
}
}
@SuppressWarnings("unused")
static class Body {
String name;
Limb[] limbArray = new Limb[0];
Collection<Limb> limbCollection = new ArrayList<Limb>();
Body(String name, Limb... limbs) {
this.name = name;
this.limbCollection = Arrays.asList(limbs);
this.limbArray = limbs;
}
public String getName() {
return name;
}
public Collection<Limb> getLimbCollection() {
return limbCollection;
}
public Limb[] getLimbArray() {
return limbArray;
}
}
@SuppressWarnings("unused")
static class Limb {
String name;
Nail[] nailArray = new Nail[0];
Collection<Nail> nailCollection = new ArrayList<Nail>();
Limb(String name, Nail... nails) {
this.name = name;
this.nailCollection = Arrays.asList(nails);
this.nailArray = nails;
}
public String getName() {
return name;
}
public Collection<Nail> getNailCollection() {
return nailCollection;
}
public Nail[] getNailArray() {
return nailArray;
}
}
static class Nail {
String colour;
private Nail(String colour) {
this.colour = colour;
}
}
}