1 
2 /**
3  *    Copyright (C) 2018-present MongoDB, Inc.
4  *
5  *    This program is free software: you can redistribute it and/or modify
6  *    it under the terms of the Server Side Public License, version 1,
7  *    as published by MongoDB, Inc.
8  *
9  *    This program is distributed in the hope that it will be useful,
10  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *    Server Side Public License for more details.
13  *
14  *    You should have received a copy of the Server Side Public License
15  *    along with this program. If not, see
16  *    <http://www.mongodb.com/licensing/server-side-public-license>.
17  *
18  *    As a special exception, the copyright holders give permission to link the
19  *    code of portions of this program with the OpenSSL library under certain
20  *    conditions as described in each individual source file and distribute
21  *    linked combinations including the program with the OpenSSL library. You
22  *    must comply with the Server Side Public License in all respects for
23  *    all of the code used other than as permitted herein. If you modify file(s)
24  *    with this exception, you may extend this exception to your version of the
25  *    file(s), but you are not obligated to do so. If you do not wish to do so,
26  *    delete this exception statement from your version. If you delete this
27  *    exception statement from all source files in the program, then also delete
28  *    it in the license file.
29  */
30 
31 #include "mongo/platform/basic.h"
32 
33 #include "mongo/db/query/collation/collator_interface_mock.h"
34 
35 #include <algorithm>
36 #include <cctype>
37 #include <string>
38 
39 #include "mongo/stdx/memory.h"
40 #include "mongo/util/assert_util.h"
41 
42 namespace mongo {
43 
44 namespace {
45 
mockTypeToString(CollatorInterfaceMock::MockType type)46 std::string mockTypeToString(CollatorInterfaceMock::MockType type) {
47     switch (type) {
48         case CollatorInterfaceMock::MockType::kReverseString:
49             return "mock_reverse_string";
50         case CollatorInterfaceMock::MockType::kAlwaysEqual:
51             return "mock_always_equal";
52         case CollatorInterfaceMock::MockType::kToLowerString:
53             return "mock_to_lower_string";
54     }
55 
56     MONGO_UNREACHABLE;
57 }
58 
59 }  // namespace
60 
CollatorInterfaceMock(MockType mockType)61 CollatorInterfaceMock::CollatorInterfaceMock(MockType mockType)
62     : CollatorInterface(CollationSpec(mockTypeToString(mockType), "mock_version")),
63       _mockType(mockType) {}
64 
clone() const65 std::unique_ptr<CollatorInterface> CollatorInterfaceMock::clone() const {
66     auto clone = stdx::make_unique<CollatorInterfaceMock>(_mockType);
67     return {std::move(clone)};
68 }
69 
compare(StringData left,StringData right) const70 int CollatorInterfaceMock::compare(StringData left, StringData right) const {
71     switch (_mockType) {
72         case MockType::kReverseString: {
73             std::string leftString = left.toString();
74             std::string rightString = right.toString();
75             std::reverse(leftString.begin(), leftString.end());
76             std::reverse(rightString.begin(), rightString.end());
77             StringData leftReversed(leftString);
78             StringData rightReversed(rightString);
79             return leftReversed.compare(rightReversed);
80         }
81         case MockType::kToLowerString: {
82             std::string leftString = left.toString();
83             std::string rightString = right.toString();
84             std::transform(leftString.begin(), leftString.end(), leftString.begin(), ::tolower);
85             std::transform(rightString.begin(), rightString.end(), rightString.begin(), ::tolower);
86             StringData leftLower(leftString);
87             StringData rightLower(rightString);
88             return leftLower.compare(rightLower);
89         }
90         case MockType::kAlwaysEqual:
91             return 0;
92     }
93 
94     MONGO_UNREACHABLE;
95 }
96 
getComparisonKey(StringData stringData) const97 CollatorInterface::ComparisonKey CollatorInterfaceMock::getComparisonKey(
98     StringData stringData) const {
99     switch (_mockType) {
100         case MockType::kReverseString: {
101             std::string keyDataString = stringData.toString();
102             std::reverse(keyDataString.begin(), keyDataString.end());
103             return makeComparisonKey(std::move(keyDataString));
104         }
105         case MockType::kToLowerString: {
106             std::string keyDataString = stringData.toString();
107             std::transform(
108                 keyDataString.begin(), keyDataString.end(), keyDataString.begin(), ::tolower);
109             return makeComparisonKey(std::move(keyDataString));
110         }
111         case MockType::kAlwaysEqual:
112             return makeComparisonKey("always_equal");
113     }
114 
115     MONGO_UNREACHABLE;
116 }
117 
118 }  // namespace mongo
119