Skip to content

Commit df3a400

Browse files
committed
JAVA-2613: Fix issues in the CustomMatcher
* include fields declared in all superclasses * do not include static fields * ensure that a field without a public accessor method can be compared Also fix one test bug that was exposed by this fix
1 parent 4a97fc3 commit df3a400

File tree

1 file changed

+50
-36
lines changed

1 file changed

+50
-36
lines changed

driver-core/src/test/unit/com/mongodb/CustomMatchers.groovy

Lines changed: 50 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ package com.mongodb
1919
import org.hamcrest.BaseMatcher
2020
import org.hamcrest.Description
2121

22+
import java.lang.reflect.Field
23+
import java.lang.reflect.Modifier
24+
2225
@SuppressWarnings('NoDef')
2326
class CustomMatchers {
2427

@@ -55,25 +58,32 @@ class CustomMatchers {
5558
if (actual.class.name != expected.class.name) {
5659
return false
5760
}
58-
getFieldNames(actual.class).findAll { !ignoreNames.contains(it) } .collect {
59-
if (nominallyTheSame(it)) {
60-
return actual."$it".class == expected."$it".class
61-
} else if (actual."$it" != expected."$it") {
62-
def (a1, e1) = [actual."$it", expected."$it"]
63-
if ([a1, e1].contains(null) && [a1, e1] != nullList) {
61+
getFields(actual.class).findAll { !ignoreNames.contains(it.name) } .collect {
62+
it.setAccessible(true)
63+
def actualPropertyValue = it.get(actual)
64+
def expectedPropertyValue = it.get(expected)
65+
66+
if (nominallyTheSame(it.name)) {
67+
return actualPropertyValue.class == expectedPropertyValue.class
68+
} else if (actualPropertyValue != expectedPropertyValue) {
69+
if ([actualPropertyValue, expectedPropertyValue].contains(null)
70+
&& [actualPropertyValue, expectedPropertyValue] != nullList) {
6471
return false
65-
} else if (List.isCase(a1) && List.isCase(e1) && (a1.size() == e1.size())) {
72+
} else if (List.isCase(actualPropertyValue) && List.isCase(expectedPropertyValue)
73+
&& (actualPropertyValue.size() == expectedPropertyValue.size())) {
6674
def i = -1
67-
return a1.collect { a -> i++; compare(a, e1[i]) }.every { it }
68-
} else if (a1.class != null && a1.class.name.startsWith('com.mongodb') && a1.class == e1.class) {
69-
return compare(a1, e1)
75+
return actualPropertyValue.collect { a -> i++; compare(a, expectedPropertyValue[i]) }.every { it }
76+
} else if (actualPropertyValue.class != null && actualPropertyValue.class.name.startsWith('com.mongodb')
77+
&& actualPropertyValue.class == expectedPropertyValue.class) {
78+
return compare(actualPropertyValue, expectedPropertyValue)
7079
}
7180
return false
7281
}
7382
true
7483
}.every { it }
7584
}
7685

86+
7787
static describer(expected, actual, description) {
7888
describer(expected, actual, [], description)
7989
}
@@ -91,48 +101,52 @@ class CustomMatchers {
91101
return false
92102
}
93103

94-
getFieldNames(actual.class).findAll { !ignoreNames.contains(it) } .collect {
104+
getFields(actual.class).findAll { !ignoreNames.contains(it.name) } .collect {
105+
it.setAccessible(true)
106+
def actualPropertyValue = it.get(actual)
107+
def expectedPropertyValue = it.get(expected)
95108
if (nominallyTheSame(it)) {
96-
if (actual."$it".class != expected."$it".class) {
97-
description.appendText("different classes $it :" +
98-
" ${expected."$it".class.name} != ${actual."$it".class.name}, ")
109+
if (actualPropertyValue.class != expectedPropertyValue.class) {
110+
description.appendText("different classes in $it.name :" +
111+
" ${expectedPropertyValue.class.name} != ${actualPropertyValue.class.name}, ")
99112
return false
100113
}
101-
} else if (actual."$it" != expected."$it") {
102-
def (a1, e1) = [actual."$it", expected."$it"]
103-
if (([a1, e1].contains(null) || [a1.class, e1.class].contains(null)) && [a1, e1] != nullList) {
104-
description.appendText("different values in $it : $e1 != $a1\n")
114+
} else if (actualPropertyValue != expectedPropertyValue) {
115+
if (([actualPropertyValue, expectedPropertyValue].contains(null)
116+
|| [actualPropertyValue.class, expectedPropertyValue.class].contains(null))
117+
&& [actualPropertyValue, expectedPropertyValue] != nullList) {
118+
description.appendText("different values in $it.name : ${expectedPropertyValue} != ${actualPropertyValue}\n")
105119
return false
106-
} else if (List.isCase(a1) && List.isCase(e1) && (a1.size() == e1.size())) {
120+
} else if (List.isCase(actualPropertyValue) && List.isCase(expectedPropertyValue)
121+
&& (actualPropertyValue.size() == expectedPropertyValue.size())) {
107122
def i = -1
108-
a1.each { a ->
109-
i++; if (!compare(a, e1[i])) {
110-
describer(a, e1[i], description)
123+
actualPropertyValue.each { a ->
124+
i++; if (!compare(a, expectedPropertyValue[i])) {
125+
describer(a, expectedPropertyValue[i], description)
111126
}
112127
}.every { it }
113-
} else if (a1.class.name.startsWith('com.mongodb') && a1.class == e1.class) {
114-
return describer(a1, e1, description)
128+
} else if (actualPropertyValue.class.name.startsWith('com.mongodb')
129+
&& actualPropertyValue.class == expectedPropertyValue.class) {
130+
return describer(actualPropertyValue, expectedPropertyValue, description)
115131
}
116-
description.appendText("different values in $it : $e1 != $a1\n")
132+
description.appendText("different values in $it.name : ${expectedPropertyValue} != ${actualPropertyValue}\n")
117133
return false
118134
}
119135
true
120136
}
121137
}
122138

123-
static List<String> getFieldNames(Class curClass) {
124-
getFieldNames(curClass, [])
125-
}
126-
127-
static List<String> getFieldNames(Class curClass, names) {
128-
if (curClass != Object) {
129-
getFieldNames(curClass.getSuperclass(), names += curClass.declaredFields.findAll { !it.synthetic }*.name)
139+
static List<Field> getFields(Class curClass) {
140+
if (curClass == Object) {
141+
return []
130142
}
131-
names
143+
def fields = getFields(curClass.getSuperclass())
144+
fields.addAll(curClass.declaredFields.findAll { !it.synthetic && !Modifier.isStatic(it.modifiers) })
145+
fields
132146
}
133147

134-
static nominallyTheSame(String className ) {
135-
className in ['decoder', 'executor']
136-
}
137148

149+
static nominallyTheSame(String propertyName ) {
150+
propertyName in ['decoder', 'executor']
151+
}
138152
}

0 commit comments

Comments
 (0)