Skip to content

Conversation

@eramongodb
Copy link
Contributor

Related to CXX-3237. #1430 added Catch::StringMaker<T> specializations for bsoncxx::v1 entities so that Catch's expression decomposition feature can translate BSON documents and elements into readable strings on assertion failures (or --success output) without requiring an "include all" test header containing all specializations (compilation performance). However, there are three specializations which contain out-of-line definitions of the convert() function: v1::array::view, v1::document::view, and v1::element::view. These definitions are not available for use by the mongocxx_mocked test library, as bsoncxx_testing is not compiled with test sources; it is merely a bsoncxx library compiled with the BSONCXX_TESTING preprocessor macro defined to control test-only symbol exports. It is not aware of Catch2, nor should it be. Consequently, when e.g. bsoncxx/test/v1/document/view.hh is included by mongocxx test sources, despite the class template specialization being visible, the convert() member function definition is not, leading to the one defined by Catch2's partial template specializations for ranges or similar (tbh I am not entirely sure why this is not a hard linker error).

To address this issue, the out-of-line definitions are isolated into *_string_maker.cpp implementation files. These files are then included as additional source files for individual mongocxx test executables via ${mongocxx_test_bsoncxx} (a variable is used instead of an object library to avoid reserving new names in the CMake global target namespace; still hoping for cmake/cmake#22687 to be addressed someday...). The new mongocxx/test/bsoncxx.cpp file validates that the correct Catch::StringMaker<T> definitions are used when stringifying bsoncxx::v1 entities (v1::document::view -> v1::element::view -> v1::types::view -> v1::array::view). The test headers are also given additional transitive includes to ensure the Catch::StringMaker<T> specializations are consistently visible prior to use (which also correspond to publically documented transitive includes).

@eramongodb eramongodb requested a review from kevinAlbs November 14, 2025 15:15
@eramongodb eramongodb self-assigned this Nov 14, 2025
@eramongodb eramongodb requested a review from a team as a code owner November 14, 2025 15:15
@eramongodb eramongodb changed the title Reuse bsoncxx::v1 out-of-line definitions of `Catch::StringMaker<T>::convert() Reuse bsoncxx::v1 out-of-line definitions of Catch::StringMaker<T>::convert() Nov 14, 2025
Copy link
Collaborator

@kevinAlbs kevinAlbs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with minor comments. I like the self test to validate the string form.

// See the License for the specific language governing permissions and
// limitations under the License.

// This file is included by mongocxx/test/v1/bsoncxx.cpp!
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove or revise comment? view_string_maker.cpp is not #includeed but rather added to the source list.

Suggested change
// This file is included by mongocxx/test/v1/bsoncxx.cpp!

Similarly applies to other *_string_maker.cpp files.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops, these are leftovers from a prior approach which directly #include'd the .cpp files rather than the ${mongocxx_test_bsoncxx} variable.


//

#include <bsoncxx/test/v1/document/view.hh>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#include <bsoncxx/test/v1/document/view.hh>

Remove unneeded header? I expect since bsoncxx::test::stringify is only called on v1::types::view in this file, the document/view.hh header is not needed.

Comment similarly applies to other *_string_maker.cpp files.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After the changes in this PR, v1/types/view.hh provides both v1/array/view.hh and v1/document/view.hh (consistency with documented transitive includes in the public headers), so this explicit include is indeed not necessary.

However, an include (transitive or otherwise) of v1/array/view.hh and v1/document/view.hh is nevertheless necessary so that the Catch::StringMaker<T> explicit template specializations are visible when potentially used by the Catch::StringMaker<v1::types::view>, as otherwise, Catch2's template definitions will be instantiated and used instead.

// Calls Catch::StringMaker<v1::types::view>::convert(). // -> may also call Catch::StringMaker<v1::array::view>::convert(). // -> may also call Catch::StringMaker<v1::document::view>::convert(). // -> ... etc. res += bsoncxx::test::stringify(iter->type_view());
@eramongodb eramongodb merged commit 2608a1e into mongodb:master Nov 14, 2025
15 of 16 checks passed
@eramongodb eramongodb deleted the cxx-abi-v1-tests branch November 14, 2025 18:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants