Skip to content

Commit ef4ce65

Browse files
committed
Implement Condition support for hasValues
1 parent 0560024 commit ef4ce65

8 files changed

+436
-11
lines changed

src/main/java/org/assertj/db/api/AbstractRowAssert.java

+13-3
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313
package org.assertj.db.api;
1414

1515
import org.assertj.db.api.assertions.AssertOnNumberOfColumns;
16+
import org.assertj.db.api.assertions.AssertOnRowCondition;
1617
import org.assertj.db.api.assertions.AssertOnRowEquality;
1718
import org.assertj.db.api.assertions.AssertOnRowNullity;
19+
import org.assertj.db.api.assertions.impl.AssertionsOnRowCondition;
1820
import org.assertj.db.api.assertions.impl.AssertionsOnValuesNullity;
1921
import org.assertj.db.api.assertions.impl.AssertionsOnNumberOfColumns;
2022
import org.assertj.db.api.assertions.impl.AssertionsOnRowEquality;
@@ -34,7 +36,8 @@
3436
* Base class for all {@link Row}s assertions.
3537
*
3638
* @author Régis Pouiller
37-
*
39+
* @author Julien Roy
40+
*
3841
* @param <D> The class of the actual value (an sub-class of {@link AbstractDbData}).
3942
* @param <A> The class of the original assertion (an sub-class of {@link AbstractDbAssert}).
4043
* @param <C> The class of the equivalent column assertion (an sub-class of {@link AbstractColumnAssert}).
@@ -49,7 +52,8 @@ public abstract class AbstractRowAssert<D extends AbstractDbData<D>, A extends A
4952
ToValueFromRow<RV>,
5053
AssertOnRowEquality<R>,
5154
AssertOnNumberOfColumns<R>,
52-
AssertOnRowNullity<R> {
55+
AssertOnRowNullity<R>,
56+
AssertOnRowCondition<R> {
5357

5458
/**
5559
* Position of navigation to value.
@@ -63,7 +67,7 @@ public abstract class AbstractRowAssert<D extends AbstractDbData<D>, A extends A
6367

6468
/**
6569
* Constructor.
66-
*
70+
*
6771
* @param originalDbAssert The original assert. That could be a {@link RequestAssert} or a {@link TableAssert}.
6872
* @param selfType Type of this assertion class : a sub-class of {@code AbstractRowAssert}.
6973
* @param valueType Class of the assert on the value : a sub-class of {@code AbstractRowValueAssert}.
@@ -146,4 +150,10 @@ public R hasValues(Object... expected) {
146150
public R hasOnlyNotNullValues() {
147151
return AssertionsOnValuesNullity.hasOnlyNotNullValues(myself, info, getValuesList());
148152
}
153+
154+
/** {@inheritDoc} */
155+
@Override
156+
public R hasValuesSatisfying(Object... expected) {
157+
return AssertionsOnRowCondition.hasValuesSatisfying(myself, info, getValuesList(), expected);
158+
}
149159
}

src/main/java/org/assertj/db/api/ChangeRowAssert.java

+12-1
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@
1313
package org.assertj.db.api;
1414

1515
import org.assertj.db.api.assertions.AssertOnNumberOfColumns;
16+
import org.assertj.db.api.assertions.AssertOnRowCondition;
1617
import org.assertj.db.api.assertions.AssertOnRowEquality;
1718
import org.assertj.db.api.assertions.AssertOnRowOfChangeExistence;
1819
import org.assertj.db.api.assertions.impl.AssertionsOnNumberOfColumns;
20+
import org.assertj.db.api.assertions.impl.AssertionsOnRowCondition;
1921
import org.assertj.db.api.assertions.impl.AssertionsOnRowEquality;
2022
import org.assertj.db.api.assertions.impl.AssertionsOnRowOfChangeExistence;
2123
import org.assertj.db.exception.AssertJDBException;
@@ -33,14 +35,16 @@
3335
* Assertion methods for a {@code Row} of a {@code Change}.
3436
*
3537
* @author Régis Pouiller
38+
* @author Julien Roy
3639
*/
3740
public class ChangeRowAssert
3841
extends AbstractAssertWithOriginWithColumnsAndRowsFromChange<ChangeRowAssert, ChangeAssert>
3942
implements RowElement,
4043
OriginWithValuesFromRow<ChangesAssert, ChangeAssert, ChangeColumnAssert, ChangeRowAssert, ChangeRowValueAssert>,
4144
AssertOnRowEquality<ChangeRowAssert>,
4245
AssertOnNumberOfColumns<ChangeRowAssert>,
43-
AssertOnRowOfChangeExistence<ChangeRowAssert> {
46+
AssertOnRowOfChangeExistence<ChangeRowAssert>,
47+
AssertOnRowCondition<ChangeRowAssert> {
4448

4549
/**
4650
* Position of navigation to value.
@@ -163,6 +167,13 @@ public ChangeRowAssert doesNotExist() {
163167
return AssertionsOnRowOfChangeExistence.doesNotExist(myself, info, row);
164168
}
165169

170+
/** {@inheritDoc} */
171+
@Override
172+
public ChangeRowAssert hasValuesSatisfying(Object... expected) {
173+
exists();
174+
return AssertionsOnRowCondition.hasValuesSatisfying(myself, info, row.getValuesList(), expected);
175+
}
176+
166177
/**
167178
* Returns to level of assertion methods on a {@link org.assertj.db.type.Change}.
168179
*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
3+
* the License. You may obtain a copy of the License at
4+
*
5+
* http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
8+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
9+
* specific language governing permissions and limitations under the License.
10+
*
11+
* Copyright 2015-2021 the original author or authors.
12+
*/
13+
package org.assertj.db.api.assertions;
14+
15+
import org.assertj.core.api.Condition;
16+
17+
/**
18+
* Defines the assertion method on the a row satisfy conditions.
19+
*
20+
* @param <T> The "self" type of this assertion class. Please read &quot;<a href="http://bit.ly/1IZIRcY"
21+
* target="_blank">Emulating 'self types' using Java Generics to simplify fluent API implementation</a>&quot;
22+
* for more details.
23+
* @author Julien Roy
24+
*/
25+
public interface AssertOnRowCondition<T extends AssertOnRowCondition<T>> {
26+
27+
/**
28+
* Verifies that the values of a row satisfy to conditions in parameter.
29+
* <p>
30+
* Example where the assertion verifies that the values in the first {@code Row} of the {@code Table} satisfy to the
31+
* conditions in parameter :
32+
* </p>
33+
*
34+
* <pre><code class='java'>
35+
* assertThat(table).row().hasValuesSatisfying(new Condition<String>(v -> v.equals("Weaver"), "isWeaver"));
36+
* </code></pre>
37+
* <p>
38+
* Example where the assertion verifies that the values of the row at end point of the first change are equal to the
39+
* values in parameter :
40+
* </p>
41+
*
42+
* <pre><code class='java'>
43+
* assertThat(changes).change().rowAtEndPoint().hasValuesSatisfying(new Condition<String>(v -> v.equals("Weaver"), "isWeaver"));
44+
* </code></pre>
45+
*
46+
* @param expected The expected conditions.
47+
* @return {@code this} assertion object.
48+
* @throws AssertionError If the values of the row are not satisfy to the conditions in parameters.
49+
* @see org.assertj.db.api.AbstractRowAssert#hasValuesSatisfying(Condition)
50+
* @see org.assertj.db.api.ChangeRowAssert#hasValuesSatisfying(Condition)
51+
*/
52+
T hasValuesSatisfying(Object... expected);
53+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
3+
* the License. You may obtain a copy of the License at
4+
*
5+
* http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
8+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
9+
* specific language governing permissions and limitations under the License.
10+
*
11+
* Copyright 2015-2021 the original author or authors.
12+
*/
13+
package org.assertj.db.api.assertions.impl;
14+
15+
import org.assertj.core.api.Condition;
16+
import org.assertj.core.api.WritableAssertionInfo;
17+
import org.assertj.core.internal.Failures;
18+
import org.assertj.db.api.AbstractAssert;
19+
import org.assertj.db.type.Value;
20+
import org.assertj.db.type.ValueType;
21+
import org.assertj.db.util.Values;
22+
23+
import java.util.List;
24+
25+
import static org.assertj.db.error.ShouldBeCompatible.shouldBeCompatible;
26+
import static org.assertj.db.error.ShouldBeEqual.shouldBeEqual;
27+
import static org.assertj.db.error.ShouldHaveColumnsSize.shouldHaveColumnsSize;
28+
import static org.assertj.db.util.Values.areEqual;
29+
30+
/**
31+
* Implements the assertion method on the matching with condition of a row.
32+
*
33+
* @author Julien Roy
34+
*
35+
* @see org.assertj.db.api.assertions.AssertOnRowCondition
36+
*/
37+
public class AssertionsOnRowCondition {
38+
39+
/**
40+
* To notice failures in the assertion.
41+
*/
42+
private static final Failures failures = Failures.instance();
43+
44+
/**
45+
* Private constructor.
46+
*/
47+
private AssertionsOnRowCondition() {
48+
// Empty
49+
}
50+
51+
public static <A extends AbstractAssert<?>> A hasValuesSatisfying(A assertion, WritableAssertionInfo info,
52+
List<Value> valuesList, Object... expected) {
53+
54+
if (valuesList.size() != expected.length) {
55+
throw failures.failure(info, shouldHaveColumnsSize(valuesList.size(), expected.length));
56+
}
57+
58+
int index = 0;
59+
for (Value value : valuesList) {
60+
Object object = expected[index];
61+
62+
if (object instanceof Condition) {
63+
Condition<Object> condition = (Condition<Object>) object;
64+
if (!condition.matches(value.getValue())) {
65+
Object actual = Values.getRepresentationFromValueInFrontOfExpected(value, object);
66+
throw failures.failure(info, shouldBeEqual(index, actual, object));
67+
}
68+
index++;
69+
continue;
70+
}
71+
72+
if (!value.isComparisonPossible(object)) {
73+
throw failures.failure(info, shouldBeCompatible(value, object));
74+
}
75+
76+
if (!areEqual(value, object)) {
77+
if (value.getValueType() == ValueType.BYTES) {
78+
throw failures.failure(info, shouldBeEqual(index));
79+
} else {
80+
Object actual = Values.getRepresentationFromValueInFrontOfExpected(value, object);
81+
throw failures.failure(info, shouldBeEqual(index, actual, object));
82+
}
83+
}
84+
85+
index++;
86+
}
87+
88+
return assertion;
89+
}
90+
}

src/main/java/org/assertj/db/api/assertions/impl/AssertionsOnRowEquality.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,8 @@ public static <A extends AbstractAssert<?>> A hasValues(A assertion, WritableAss
6969
if (value.getValueType() == ValueType.BYTES) {
7070
throw failures.failure(info, shouldBeEqual(index));
7171
} else {
72-
throw failures.failure(info, shouldBeEqual(index, Values.getRepresentationFromValueInFrontOfExpected(value,
73-
expected[index]),
74-
expected[index]));
72+
Object actual = Values.getRepresentationFromValueInFrontOfExpected(value, expected[index]);
73+
throw failures.failure(info, shouldBeEqual(index, actual, expected[index]));
7574
}
7675
}
7776
index++;

src/main/java/org/assertj/db/navigation/PositionWithChanges.java

+3-4
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ public E getChangesInstance(Changes changes, ChangeType changeType, String table
125125
}
126126

127127
try {
128-
Class clazz = unProxy(myself.getClass());
128+
Class<?> clazz = unProxy(myself.getClass());
129129
Constructor<E> constructor = actualElementClass.getDeclaredConstructor(clazz, Changes.class);
130130
instance = constructor.newInstance(myself, nextChanges);
131131
instance.as(getChangesDescription(changeType, tableName));
@@ -200,7 +200,7 @@ public N getChangeInstance(Changes changes, ChangeType changeType, String tableN
200200
}
201201

202202
try {
203-
Class clazz = unProxy(myself.getClass());
203+
Class<?> clazz = unProxy(myself.getClass());
204204
Constructor<N> constructor = nextElementClass.getDeclaredConstructor(clazz, Change.class);
205205
instance = constructor.newInstance(myself, change);
206206
instance.as(getChangeDescription(changes, change, index, changeType, tableName));
@@ -248,8 +248,7 @@ public N getChangeInstanceWithPK(Changes changes, String tableName, Object... pk
248248
}
249249
index++;
250250
}
251-
throw new AssertJDBException("No change found for table " + tableName + " and primary keys " + Arrays
252-
.asList(pksValues));
251+
throw new AssertJDBException("No change found for table " + tableName + " and primary keys " + Arrays.asList(pksValues));
253252
}
254253

255254
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
3+
* the License. You may obtain a copy of the License at
4+
*
5+
* http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
8+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
9+
* specific language governing permissions and limitations under the License.
10+
*
11+
* Copyright 2015-2021 the original author or authors.
12+
*/
13+
package org.assertj.db.api.assertions;
14+
15+
import org.assertj.core.api.Assertions;
16+
import org.assertj.core.api.Condition;
17+
import org.assertj.core.api.HamcrestCondition;
18+
import org.assertj.db.api.ChangeRowAssert;
19+
import org.assertj.db.api.TableRowAssert;
20+
import org.assertj.db.common.AbstractTest;
21+
import org.assertj.db.common.NeedReload;
22+
import org.assertj.db.type.Changes;
23+
import org.assertj.db.type.Table;
24+
import org.hamcrest.CoreMatchers;
25+
import org.junit.Test;
26+
27+
import java.util.UUID;
28+
29+
import static org.assertj.db.api.Assertions.assertThat;
30+
31+
/**
32+
* Tests on {@link AssertOnRowCondition} class :
33+
* {@link AssertOnRowCondition#hasValuesSatisfying(Object...)} method.
34+
*
35+
* @author Julien Roy
36+
*
37+
*/
38+
public class AssertOnRowCondition_HasValuesSatisfying_Test extends AbstractTest {
39+
40+
/**
41+
* This method tests the {@code hasValuesSatisfying} assertion method.
42+
*/
43+
@Test
44+
@NeedReload
45+
public void test_has_values() {
46+
Table table = new Table(source, "actor");
47+
Changes changes = new Changes(table).setStartPointNow();
48+
updateChangesForTests();
49+
changes.setEndPointNow();
50+
51+
ChangeRowAssert changeRowAssert = assertThat(changes).change().rowAtEndPoint();
52+
ChangeRowAssert changeRowAssert2 = changeRowAssert
53+
.hasValuesSatisfying(
54+
4,
55+
new Condition<String>(v -> v.equals("Murray"), "isMurray"),
56+
new HamcrestCondition<>(CoreMatchers.is("Bill")),
57+
"1950-09-21",
58+
"30B443AE-C0C9-4790-9BEC-CE1380808435"
59+
)
60+
.hasValues(4, "Murray", "Bill", "1950-09-21", UUID.fromString("30B443AE-C0C9-4790-9BEC-CE1380808435"));
61+
Assertions.assertThat(changeRowAssert).isSameAs(changeRowAssert2);
62+
63+
TableRowAssert tableRowAssert = assertThat(table).row();
64+
TableRowAssert tableRowAssert2 = tableRowAssert
65+
.hasValues(1, "Weaver", "Susan Alexandra", "1949-10-08", "30B443AE-C0C9-4790-9BEC-CE1380808435")
66+
.hasValues(1, "Weaver", "Susan Alexandra", "1949-10-08", UUID.fromString("30B443AE-C0C9-4790-9BEC-CE1380808435"));
67+
Assertions.assertThat(tableRowAssert).isSameAs(tableRowAssert2);
68+
}
69+
70+
/**
71+
* This method should fail because the values are different.
72+
*/
73+
@Test
74+
@NeedReload
75+
public void should_fail_because_values_are_different() {
76+
Table table = new Table(source, "actor");
77+
Changes changes = new Changes(table).setStartPointNow();
78+
updateChangesForTests();
79+
changes.setEndPointNow();
80+
81+
try {
82+
assertThat(changes).change().rowAtEndPoint()
83+
.hasValues(4, "Murray", "Billy", "1950-09-21", UUID.fromString("30B443AE-C0C9-4790-9BEC-CE1380808435"));
84+
} catch (AssertionError e) {
85+
Assertions.assertThat(e.getMessage()).isEqualTo(String.format(
86+
"[Row at end point of Change at index 0 (with primary key : [4]) of Changes on ACTOR table of 'sa/jdbc:h2:mem:test' source] %n"
87+
+ "Expecting that the value at index 2:%n"
88+
+ " <\"Bill\">%n"
89+
+ "to be equal to: %n"
90+
+ " <\"Billy\">"));
91+
}
92+
try {
93+
assertThat(table).row().hasValues(1, "Weaver", "Sigourney", "1949-10-08",
94+
UUID.fromString("648DFAC8-14AC-47F7-95CF-3475525A3BE3"));
95+
} catch (AssertionError e) {
96+
Assertions.assertThat(e.getMessage()).isEqualTo(String.format("[Row at index 0 of ACTOR table] %n"
97+
+ "Expecting that the value at index 2:%n"
98+
+ " <\"Susan Alexandra\">%n"
99+
+ "to be equal to: %n"
100+
+ " <\"Sigourney\">"));
101+
}
102+
}
103+
}

0 commit comments

Comments
 (0)