/* * Created on May 26, 2010 * * 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. * * Copyright @2010-2013 the original author or authors. */ package org.fest.assertions; import org.fest.test.ExpectedException; import org.fest.util.IntrospectionError; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import java.util.Collection; import java.util.List; import static java.util.Collections.emptyList; import static org.fest.assertions.FailureMessages.actualIsNull; import static org.fest.assertions.Title.*; import static org.fest.test.ExpectedException.none; import static org.fest.util.Lists.newArrayList; import static org.junit.Assert.assertEquals; /** * Base class for testing implementations of {@link ObjectGroupAssert#onProperty(String)}. * * @param <S> used to simulate "self types." For more information please read "<a href="http://goo.gl/fjgOM" * target="_blank">Emulating 'self types' using Java Generics to simplify fluent API implementation</a>." * @param <A> The type supported by the implementation of the {@code ObjectGroupAssert} to test. * @author Joel Costigliola * @author Alex Ruiz */ public abstract class ObjectGroupAssert_onProperty_Test<S extends ObjectGroupAssert<S, A>, A> { @Rule public ExpectedException thrown = none(); private List<Person> persons; @Before public void setUp() { persons = newArrayList(populateData()); } private static Collection<Person> populateData() { /* * Person properties : - Long id; - Name name; - Person father; - int age; - long socialSecurityNumber; - boolean * male; - char favoriteAlphabetLetter; - byte favoriteByte; - short yearOfBirth; - float height; - double weight; - * String homeTown; */ List<Person> persons = newArrayList(); Person pier = new Person(1L, "Pier", 25, 6L, true, 'P', 1, 1974, 1.90f, 80.1, "Paris"); pier.setFather(new Person(11L, "PierFather", 55, 6L, true, 'P', 1, 1974, 1.90f, 80.1, "Paris")); persons.add(pier); Person paula = new Person(2L, "Paula", 32, 67L, false, 'O', 2, 1975, 1.80f, 90.2, "Madrid"); paula.setFather(new Person(22L, "PaulaFather", 62, 67L, false, 'O', 2, 1975, 1.80f, 90.2, "Madrid")); paula.setTitle(Miss); persons.add(paula); Person jack = new Person(3L, "Jack", 16, 678L, false, 'J', 4, 1976, 1.70f, 100.3, "London"); jack.setFather(new Person(33L, "JackFather", 46, 678L, false, 'J', 4, 1976, 1.70f, 100.3, "London")); persons.add(jack); Person otherJack = new Person(4L, "Jack", 44, 6789L, true, 'K', 8, 1977, 1.60f, 110.4, "Roma"); otherJack.setFather(new Person(44L, "OtherJackFather", 74, 678L, false, 'J', 4, 1976, 1.70f, 100.3, "Roma")); persons.add(otherJack); return persons; } @Test public final void should_pass_on_non_primitive_type_property() { assertionsFor(persons).onProperty("id").contains(1L, 2L, 4L); assertionsFor(persons).onProperty("homeTown").contains("Paris", "Roma", "London", "Madrid"); } @Test public final void should_pass_on_enum_type_property() { assertionsFor(persons).onProperty("title").contains(Mr, Miss); } @Test public final void should_pass_on_primitive_type_int_property() { assertionsFor(persons).onProperty("age").containsOnly(25, 16, 44, 32); } @Test public final void should_pass_on_primitive_type_long_property() { assertionsFor(persons).onProperty("socialSecurityNumber").containsOnly(6L, 67L, 678L, 6789L); } @Test public final void should_pass_on_primitive_type_short_property() { assertionsFor(persons).onProperty("yearOfBirth").containsOnly((short) 1974, (short) 1975, (short) 1976, (short) 1977); } @Test public final void should_pass_on_primitive_type_float_property() { assertionsFor(persons).onProperty("height").containsOnly(1.90f, 1.80f, 1.70f, 1.60f); } @Test public final void should_pass_on_primitive_type_double_property() { assertionsFor(persons).onProperty("weight").containsOnly(80.1, 90.2, 100.3, 110.4); } @Test public final void should_pass_on_primitive_type_boolean_property() { assertionsFor(persons).onProperty("male").containsOnly(true, false, false, true); } @Test public final void should_pass_on_primitive_type_byte_property() { assertionsFor(persons).onProperty("favoriteByte").containsOnly((byte) 1, (byte) 2, (byte) 4, (byte) 8); } @Test public final void should_pass_on_primitive_type_char_property() { ObjectGroupAssert<S, A> assertions = assertionsFor(persons); assertions.onProperty("favoriteAlphabetLetter").contains('P', 'K'); assertions.onProperty("favoriteAlphabetLetter").containsOnly('O', 'J', 'P', 'K'); } @Test public final void should_pass_on_non_primitive_type_nested_property() { ObjectGroupAssert<S, A> assertions = assertionsFor(persons); assertions.onProperty("name.firstName").contains("Pier", "Paula", "Jack"); assertions.onProperty("father.name.firstName").containsOnly("PierFather", "PaulaFather", "JackFather", "OtherJackFather"); } @Test public final void should_pass_on_enum_type_nested_property() { assertionsFor(persons).onProperty("father.title").containsOnly(Mr, Mr, Mr, Mr); } @Test public final void should_pass_on_primitive_type_nested_property() { assertionsFor(persons).onProperty("father.age").containsOnly(55, 46, 74, 62); } @Test public final void should_fail_on_non_primitive_type_property() { String message = "<['Paris', 'Madrid', 'London', 'Roma']> does not contain element(s):<['Rome', 'Londres']>"; thrown.expect(AssertionError.class, message); assertionsFor(persons).onProperty("homeTown").contains("Paris", "Rome", "Londres", "Madrid"); } @Test public final void should_fail_on_non_primitive_type_nested_property() { String message = "<['Pier', 'Paula', 'Jack', 'Jack']> does not contain element(s):<['TOTO']>"; thrown.expect(AssertionError.class, message); assertionsFor(persons).onProperty("name.firstName").contains("Jack", "Pier", "TOTO", "Paula"); } @Test public final void should_fail_on_enum_type_property() { String message = "<[Mr, Miss, Mr, Mr]> does not contain element(s):<[Ms]>"; thrown.expect(AssertionError.class, message); assertionsFor(persons).onProperty("title").contains(Mr, Ms); } @Test public final void should_fail_on_enum_type_nested_property() { String message = "<[Mr, Mr, Mr, Mr]> does not contain element(s):<[Miss]>"; thrown.expect(AssertionError.class, message); assertionsFor(persons).onProperty("father.title").contains(Miss); } @Test public final void should_fail_on_primitive_type_property() { String message = "<[25, 32, 16, 44]> does not contain element(s):<[777]>"; thrown.expect(AssertionError.class, message); assertionsFor(persons).onProperty("age").contains(777); } @Test public final void should_fail_on_primitive_type_nested_property() { String message = "<[55, 62, 46, 74]> does not contain element(s):<[888]>"; thrown.expect(AssertionError.class, message); assertionsFor(persons).onProperty("father.age").contains(888); } @Test public final void should_fail_because_of_unknown_property() { try { // expected failure: Person.name does not have a 'nickname' property assertionsFor(persons).onProperty("name.nickname").containsOnly("PaulaFather", "JackFather", "OtherJackFather"); } catch (IntrospectionError e) { assertEquals("No getter for property 'nickname' in org.fest.assertions.Name", e.getMessage()); } } @Test public final void should_fail_because_of_non_public_getter() { thrown.expect(IntrospectionError.class, "No public getter for property 'country' in org.fest.assertions.Person"); assertionsFor(persons).onProperty("country").containsOnly("Spain"); } @Test public final void should_fail_because_of_no_getter() { thrown.expect(IntrospectionError.class, "No getter for property 'favoriteSport' in org.fest.assertions.Person"); assertionsFor(persons).onProperty("favoriteSport").containsOnly("soccer"); } @Test public final void should_pass_even_if_actual_contains_null_elements() { persons.add(null); assertionsFor(persons).onProperty("father.name.firstName").containsOnly("PierFather", "PaulaFather", "JackFather", "OtherJackFather"); } @Test public final void should_pass_with_null_nested_property_in_actual_elements() { persons.iterator().next().setFather(null); assertionsFor(persons).onProperty("father.name.firstName").containsOnly("PaulaFather", "JackFather", "OtherJackFather"); } @Test public final void should_pass_with_null_property_in_actual_elements() { nullifyIdsEqualTo(1); assertionsFor(persons).onProperty("id").contains(2L, 3L, 4L); assertionsFor(persons).onProperty("id").containsOnly(2L, 3L, 4L, null); nullifyAllIds(); assertionsFor(persons).onProperty("id").containsOnly(null, null, null, null); } private void nullifyIdsEqualTo(long id) { for (Person person : persons) { if (person.getId() == id) { person.setId(null); } } } private void nullifyAllIds() { for (Person person : persons) { person.setId(null); } } @Test public final void should_pass_if_actual_is_empty() { assertionsFor(emptyList()).onProperty("id").isEmpty(); } @Test public final void should_fail_if_actual_is_null() { thrown.expect(AssertionError.class, actualIsNull()); assertionsFor(null).onProperty("homeTown").contains("Paris", "Roma", "London", "Madrid"); } @Test public void should_pass_on_property_defined_at_object_class_level() { assertionsFor(persons).onProperty("class").containsOnly(Person.class); } protected abstract ObjectGroupAssert<S, A> assertionsFor(Collection<?> data); }