the Compartmented Robust Posix C++ Unit Test system |
|
---|
Collating strings is to compare their sort order, according to the rules of a locale. The result of a comparison may be different depending on the locale used.
With crpcut it is easy to make the comparison.
The result of crpcut::collate
can be compared against a string using the comparison operators
<, <=, !=, ==, >=, and > using the
ASSERT_TRUE(expr)
,
VERIFY_TRUE(expr)
,
ASSERT_FALSE(expr)
or the
VERIFY_FALSE(expr)
macro.
macro.
Note | |
---|---|
Operator == in a collation check does not mean strict equality, but rather that the left hand side and right hand side are equitable in the sort order of the locale. |
Consider this class that can represent a range of names sorted in a desired locale:
#include <set> #include <string> #include <algorithm> template <const char *(&locname)> class sorted_names { class comparator { typedef std::collate<char> coll_t; public: comparator() : loc(locname) {} bool operator()(const std::string &lh, const std::string &rh) const { const coll_t &coll = std::use_facet<coll_t>(loc); return coll.compare(lh.c_str(), lh.c_str()+lh.length(), rh.c_str(), rh.c_str()+rh.length()) < 0; } std::locale loc; }; typedef std::multiset<std::string, comparator> collection; public: typedef typename collection::const_iterator iterator; void push(std::string name) { names.insert(name); } iterator begin() const { return names.begin(); } iterator end() { return names.end(); } private: collection names; };
Working with locales in C++ is a headache, but writing the test program with crpcut isn't too bad:
#include <crpcut.hpp> #include "sorted-names.hpp" #define aring "\xc3\xa5" #define auml "\xc3\xa4" #define ouml "\xc3\xb6" #define Aring "\xc3\x85" #define Auml "\xc3\x84" #define Ouml "\xc3\x96" template <const char *(&locname)> class name_fixture { protected: name_fixture() { names.push(Auml "ngla"); names.push(Ouml "rjan"); names.push(Auml "rlig"); names.push("Bj" ouml "rn"); } sorted_names<locname> names; }; template <const char *(&locname)> class sort_checker { public: template <typename iter> static void verify(iter b, iter e) { iter i = b++; while (b != e) { INFO << *i << "<=" << *b; ASSERT_TRUE(crpcut::collate(*i, std::locale(locname)) <= *b); i = b++; } } }; const char *sv_SE = "sv_SE.utf8"; const char *de_DE = "de_DE.utf8"; TEST(coll_equal, name_fixture<sv_SE>) { sort_checker<sv_SE>::verify(names.begin(), names.end()); } TEST(coll_mismatch, name_fixture<de_DE>) { sort_checker<sv_SE>::verify(names.begin(), names.end()); } int main(int argc, char *argv[]) { return crpcut::run(argc, argv); }
See “Fixtures for common test setups” for more information on using fixtures to reduce code repetition in tests.
The result of the run is:
PASSED!: coll_equal info--------------------------------------------------------------------------- samples/collate_example.cpp:62 Björn<=Ängla ------------------------------------------------------------------------------- info--------------------------------------------------------------------------- samples/collate_example.cpp:62 Ängla<=Ärlig ------------------------------------------------------------------------------- info--------------------------------------------------------------------------- samples/collate_example.cpp:62 Ärlig<=Örjan =============================================================================== FAILED!: coll_mismatch info--------------------------------------------------------------------------- samples/collate_example.cpp:62 Ängla<=Ärlig ------------------------------------------------------------------------------- info--------------------------------------------------------------------------- samples/collate_example.cpp:62 Ärlig<=Björn ------------------------------------------------------------------------------- phase="running" -------------------------------------------------------------- samples/collate_example.cpp:63 ASSERT_TRUE(crpcut::collate(*i, std::locale(locname)) <= *b) is evaluated as: Failed in locale "sv_SE.utf8" with left hand value = "Ärlig" and right hand value = "Björn" ------------------------------------------------------------------------------- =============================================================================== 2 test cases selected Sum Critical Non-critical PASSED : 1 1 0 FAILED : 1 1 0
Collations can be tested after translation to upper- or lower-case using a templated version of crpcut::collate. Please see crpcut::collate in the reference manual for details.