From 7013288a0a85631f6978ac37ce95d1a47c59c961 Mon Sep 17 00:00:00 2001 From: Pascal Schumacher Date: Thu, 23 Jun 2016 22:25:17 +0200 Subject: [PATCH] add BDDAssertions (closes #41) --- .../org/assertj/db/api/BDDAssertions.java | 164 ++++++++++++++++++ .../db/api/EntryPointsComparison_Test.java | 77 ++++++++ 2 files changed, 241 insertions(+) create mode 100644 src/main/java/org/assertj/db/api/BDDAssertions.java create mode 100644 src/test/java/org/assertj/db/api/EntryPointsComparison_Test.java diff --git a/src/main/java/org/assertj/db/api/BDDAssertions.java b/src/main/java/org/assertj/db/api/BDDAssertions.java new file mode 100644 index 00000000..cbf9de33 --- /dev/null +++ b/src/main/java/org/assertj/db/api/BDDAssertions.java @@ -0,0 +1,164 @@ +/** + * 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 2012-2016 the original author or authors. + */ +package org.assertj.db.api; + +import org.assertj.db.exception.AssertJDBException; +import org.assertj.db.type.Changes; +import org.assertj.db.type.Request; +import org.assertj.db.type.Source; +import org.assertj.db.type.Table; + +import java.io.*; + +import static org.assertj.db.util.Descriptions.getDescription; + +/** + * Behavior Driven Development style entry point for all assertion methods. + *

+ * The difference with the {@link Assertions} class is that the entry point methods are named then + * instead of assertThat. + *

+ * The navigation methods are defined in navigation package.
+ * The assertion methods are defined in assertions package. + *

+ *

+ * Example with a {@link Source} and a {@link Table} with test on the content on the first row of the {@code movie} + * table that the {@code title} column contains "Alien" as text and the next column contains 1979 as a number : + *

+ * + *
+ * 
+ * Source source = new Source("jdbc:h2:mem:test", "sa", "");
+ * Table table = new Table(source, "movie");
+ * then(table)
+ *     .row()
+ *        .value("title")
+ *            .isEqualTo("Alien")
+ *        .returnToRow()
+ *        .value()
+ *            .isEqualTo(1979);
+ * 
+ * 
+ * + *

+ * It is possible to chain assertion on a value : + *

+ * + *
+ * 
+ * then(table)
+ *     .row()
+ *         .value("title")
+ *             .isText()
+ *             .isEqualTo("Alien");
+ * 
+ * 
+ * + *

+ * It is not necessary to use the returnToXxxx methods. The next example is equivalent to the first : + *

+ * + *
+ * 
+ * Source source = new Source("jdbc:h2:mem:test", "sa", "");
+ * Table table = new Table(source, "movie");
+ * then(table)
+ *     .row()
+ *        .value("title")
+ *            .isEqualTo("Alien")
+ *        .value()
+ *            .isEqualTo(1979);
+ * 
+ * 
+ * + *

+ * It is possible to do the same thing with column and the row : + *

+ * + *
+ * 
+ * then(table)
+ *     .row()
+ *        .value("title")
+ *            .isEqualTo("Alien")
+ *     .row()
+ *        .value()
+ *            .isEqualTo("The Village")
+ *     .column("year")
+ *         .value(1)
+ *            .equalTo(2004);
+ * 
+ * 
+ */ +public final class BDDAssertions { + + /** + * Private constructor of the entry point. + */ + private BDDAssertions() { + // empty + } + + /** + * Creates a new instance of {@link TableAssert}. + * + * @param table The table to assert on. + * @return The created assertion object. + */ + public static TableAssert then(Table table) { + return new TableAssert(table).as(getDescription(table)); + } + + /** + * Creates a new instance of {@link RequestAssert}. + * + * @param request The request to assert on. + * @return The created assertion object. + */ + public static RequestAssert then(Request request) { + return new RequestAssert(request).as(getDescription(request)); + } + + /** + * Creates a new instance of {@link ChangesAssert}. + * + * @param changes The changes to assert on. + * @return The created assertion object. + */ + public static ChangesAssert then(Changes changes) { + return new ChangesAssert(changes).as(getDescription(changes)); + } + + /** + * Reads the bytes from a file and returns them. + * + * @param file The {@link File} + * @return The bytes of the file. + * @throws NullPointerException If the {@code file} field is {@code null}. + * @throws AssertJDBException If triggered, this exception wrap a possible {@link IOException} during the loading. + */ + public static byte[] bytesContentOf(File file) { + return Assertions.bytesContentOf(file); + } + + /** + * Reads the bytes from a file in the classpath and returns them. + * + * @param resource The name of the file in the classpath. + * @return The bytes of the file. + * @throws NullPointerException If the {@code resource} field is {@code null}. + */ + public static byte[] bytesContentFromClassPathOf(String resource) { + return Assertions.bytesContentFromClassPathOf(resource); + } +} diff --git a/src/test/java/org/assertj/db/api/EntryPointsComparison_Test.java b/src/test/java/org/assertj/db/api/EntryPointsComparison_Test.java new file mode 100644 index 00000000..b1131134 --- /dev/null +++ b/src/test/java/org/assertj/db/api/EntryPointsComparison_Test.java @@ -0,0 +1,77 @@ +/** + * 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 2012-2016 the original author or authors. + */ +package org.assertj.db.api; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Set; + +import org.assertj.core.util.Sets; +import org.junit.Test; + +public class EntryPointsComparison_Test { + + private static final int ACCESS_MODIFIERS = Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE; + private static final Comparator IGNORING_DECLARING_CLASS_AND_METHOD_NAME = internalMethodComparator(true, false, true); + + @Test + public void assertions_and_bdd_assertions_should_have_the_same_methods() { + Method[] thenMethods = findMethodsWithName(BDDAssertions.class, "then"); + Method[] assertThatMethods = findMethodsWithName(Assertions.class, "assertThat"); + + assertThat(thenMethods).usingElementComparator(IGNORING_DECLARING_CLASS_AND_METHOD_NAME) + .containsExactlyInAnyOrder(assertThatMethods); + } + + private static Method[] findMethodsWithName(Class clazz, String name, Class... ignoredReturnTypes) { + List matchingMethods = new ArrayList<>(); + Set> ignoredReturnTypesSet = Sets.newLinkedHashSet(ignoredReturnTypes); + for (Method method : clazz.getMethods()) { + if (!ignoredReturnTypesSet.contains(method.getReturnType()) && method.getName().equals(name)) { + matchingMethods.add(method); + } + } + return matchingMethods.toArray(new Method[matchingMethods.size()]); + } + + private static Comparator internalMethodComparator(final boolean ignoreDeclaringClass, + final boolean ignoreReturnType, + final boolean ignoreMethodName) { + return new Comparator() { + @Override + public int compare(Method method1, Method method2) { + + // the methods should be with the same access type + boolean equal = (ACCESS_MODIFIERS & method1.getModifiers() & method2.getModifiers()) != 0; + equal = equal && (ignoreDeclaringClass || method1.getDeclaringClass().equals(method2.getDeclaringClass())); + equal = equal && (ignoreReturnType || method1.getReturnType().equals(method2.getReturnType())); + equal = equal && (ignoreMethodName || method1.getName().equals(method2.getName())); + + Class[] pTypes1 = method1.getParameterTypes(); + Class[] pTypes2 = method2.getParameterTypes(); + equal = equal && pTypes1.length == pTypes2.length; + if (equal) { + for (int i = 0; i < pTypes1.length; i++) { + equal = equal && pTypes1[i].equals(pTypes2[i]); + } + } + return equal ? 0 : 1; + } + }; + } +}