Prior to this commit, the exists() method in JsonPathExpectationsHelper
correctly asserted that the evaluated JsonPath expression resulted in a
value (i.e., that a non-null value exists); however, if the value was
an empty array, the exists() method always threw an AssertionError.
The existing behavior makes sense if the JsonPath expression is
'indefinite' -- for example, if the expression uses a filter to select
results based on a predicate for which there is no match in the JSON
document, but the existing behavior is illogical and therefore invalid
if the JsonPath expression is 'definite' (i.e., directly references an
array in the JSON document that exists but happens to be empty). For
example, prior to this commit, the following threw an AssertionError.
new JsonPathExpectationsHelper("$.arr").exists("{ 'arr': [] }");
Similar arguments can be made for the doesNotExist() method.
After thorough analysis of the status quo, it has become apparent that
the existing specialized treatment of arrays is a result of the fact
that the JsonPath library always returns an empty list if the path is
an 'indefinite' path that does not evaluate to a specific result.
Consult the discussion on "What is Returned When?" in the JsonPath
documentation for details:
https://github.com/jayway/JsonPath#what-is-returned-when
This commit addresses these issues by ensuring that empty arrays are
considered existent if the JsonPath expression is definite but
nonexistent if the expression is indefinite.
Issue: SPR-13351
Prior to this commit, a JsonPath assertion that a path expression
evaluated to an array in JsonPathExpectationsHelper (and therefore
indirectly in JsonPathResultMatchers in Spring MVC Test) would
incorrectly fail if the array was present in the JSON content but empty.
This commit fixes this issue by removing the "not empty" check for
arrays and lists.
Issue: SPR-13320
SocketUtils is used to find available ports on localhost; however,
prior to this commit, SocketUtils incorrectly reported a port as
available on localhost if another process was already bound to
localhost on the given port but not to other network interfaces. In
other words, SocketUtils determined that a given port was available for
some interface though not necessarily for the loopback interface.
This commit addresses this issue by refactoring SocketUtils so that it
tests the loopback interface to ensure that the port is actually
available for localhost.
Issue: SPR-13321
This commit introduces an additional test case to ensure that explicit
local attribute aliases (configured via @AliasFor) do not accidentally
override attributes of the same names in meta-annotations (i.e., by
convention).
Issue: SPR-13325
Prior to this commit, attempting to synthesize an annotation from a map
of annotation attributes that contained nested maps instead of nested
annotations would result in an exception.
This commit addresses this issue by properly synthesizing nested maps
and nested arrays of maps into nested annotations and nested arrays of
annotations, respectively.
Issue: SPR-13338
It is a configuration error if an alias is declared via @AliasFor for
an attribute in a meta-annotation and the meta-annotation is not
meta-present. However, prior to this commit, the support for validating
the configuration of @AliasFor in AnnotationUtils currently silently
ignored such errors.
This commit fixes this by throwing an AnnotationConfigurationException
whenever a required meta-annotation is not present or meta-present on
an annotation that declares an explicit alias for an attribute in the
meta-annotation.
Issue: SPR-13335
Prior to this commit, MockHttpServletRequestBuilder always supplied an
array of cookies to the MockHttpServletRequest that it built, even if
the array was empty.
However, this violates the contract of HttpServletRequest. According to
the Servlet API, the getCookies() method "returns null if no cookies
were sent."
This commit ensures that MockHttpServletRequestBuilder no longer
configures an empty array of cookies in the mock request that it builds.
Issue: SPR-13314
This commit introduces the following methods in JsonPathResultMatchers
in the Spring MVC Test framework.
- isString()
- isBoolean()
- isNumber()
- isMap()
In addition, this commit overhauls the Javadoc in
JsonPathResultMatchers and JsonPathExpectationsHelper.
Issue: SPR-13320
This commit aims to improve the space and time performance of
NumberUtils by invoking valueOf() factory methods instead of the
corresponding constructors when converting a number to a target class.
Prior to this commit, an explicit override for an attribute in a
meta-annotation configured via @AliasFor could potentially result in an
incorrect override of an attribute of the same name but in the wrong
meta-annotation.
This commit fixes the algorithm in getAliasedAttributeName(Method,
Class) in AnnotationUtils by ensuring that an explicit attribute
override is only applied to the configured target meta-annotation
(i.e., configured via the 'annotation' attribute in @AliasFor).
Issue: SPR-13325