1 /*
2 * Copyright (C) 2020 Matthieu Gautier <mgautier@kymeria.fr>
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied
11 * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and
12 * NON-INFRINGEMENT. See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 *
18 */
19
20 #include "../src/dirent_lookup.h"
21 #include "../src/_dirent.h"
22 #include <zim/zim.h>
23
24 #include "gtest/gtest.h"
25
26 #include <vector>
27 #include <string>
28 #include <utility>
29
30 namespace
31 {
32
33 const std::vector<std::pair<char, std::string>> articleurl = {
34 {'A', "aa"}, //0
35 {'A', "aaaa"}, //1
36 {'A', "aaaaaa"}, //2
37 {'A', "aaaabb"}, //3
38 {'A', "aaaacc"}, //4
39 {'A', "aabbaa"}, //5
40 {'A', "aabbbb"}, //6
41 {'A', "aabbcc"}, //7
42 {'A', "cccccc"}, //8
43 {'M', "foo"}, //9
44 {'a', "aa"}, //10
45 {'a', "bb"}, //11
46 {'b', "aa"} //12
47 };
48
49 struct GetDirentMock
50 {
getCountArticles__anona6f9f3d80111::GetDirentMock51 zim::article_index_t getCountArticles() const {
52 return zim::article_index_t(articleurl.size());
53 }
54
getDirent__anona6f9f3d80111::GetDirentMock55 std::shared_ptr<const zim::Dirent> getDirent(zim::article_index_t idx) const {
56 auto info = articleurl.at(idx.v);
57 auto ret = std::make_shared<zim::Dirent>();
58 ret->setUrl(info.first, info.second);
59 return ret;
60 }
61 };
62
63 class NamespaceTest : public :: testing::Test
64 {
65 protected:
66 GetDirentMock impl;
67 };
68
TEST_F(NamespaceTest,BeginOffset)69 TEST_F(NamespaceTest, BeginOffset)
70 {
71 auto result = zim::getNamespaceBeginOffset(impl, 'a');
72 ASSERT_EQ(result.v, 10);
73
74 result = zim::getNamespaceBeginOffset(impl, 'b');
75 ASSERT_EQ(result.v, 12);
76
77 result = zim::getNamespaceBeginOffset(impl, 'c');
78 ASSERT_EQ(result.v, 13);
79
80 result = zim::getNamespaceBeginOffset(impl, 'A'-1);
81 ASSERT_EQ(result.v, 0);
82
83 result = zim::getNamespaceBeginOffset(impl, 'A');
84 ASSERT_EQ(result.v, 0);
85
86 result = zim::getNamespaceBeginOffset(impl, 'M');
87 ASSERT_EQ(result.v, 9);
88
89 result = zim::getNamespaceBeginOffset(impl, 'U');
90 ASSERT_EQ(result.v, 10);
91 }
92
TEST_F(NamespaceTest,EndOffset)93 TEST_F(NamespaceTest, EndOffset)
94 {
95 auto result = zim::getNamespaceEndOffset(impl, 'a');
96 ASSERT_EQ(result.v, 12);
97
98 result = zim::getNamespaceEndOffset(impl, 'b');
99 ASSERT_EQ(result.v, 13);
100
101 result = zim::getNamespaceEndOffset(impl, 'c');
102 ASSERT_EQ(result.v, 13);
103
104 result = zim::getNamespaceEndOffset(impl, 'A'-1);
105 ASSERT_EQ(result.v, 0);
106
107 result = zim::getNamespaceEndOffset(impl, 'A');
108 ASSERT_EQ(result.v, 9);
109
110 result = zim::getNamespaceEndOffset(impl, 'M');
111 ASSERT_EQ(result.v, 10);
112
113 result = zim::getNamespaceEndOffset(impl, 'U');
114 ASSERT_EQ(result.v, 10);
115 }
116
TEST_F(NamespaceTest,EndEqualStartPlus1)117 TEST_F(NamespaceTest, EndEqualStartPlus1)
118 {
119 for (char ns=32; ns<127; ns++){
120 std::cout << "ns: " << ns << "|" << (int)ns << std::endl;
121 ASSERT_EQ(zim::getNamespaceEndOffset(impl, ns).v, zim::getNamespaceBeginOffset(impl, ns+1).v);
122 }
123 }
124
125
126 class FindxTest : public :: testing::Test
127 {
128 protected:
129 GetDirentMock impl;
130 };
131
TEST_F(FindxTest,ExactMatch)132 TEST_F(FindxTest, ExactMatch)
133 {
134 zim::DirentLookup<GetDirentMock> dl(&impl, 4);
135 auto result = dl.find('A', "aa");
136 ASSERT_EQ(result.first, true);
137 ASSERT_EQ(result.second.v, 0);
138
139 result = dl.find('a', "aa");
140 ASSERT_EQ(result.first, true);
141 ASSERT_EQ(result.second.v, 10);
142
143 result = dl.find('A', "aabbbb");
144 ASSERT_EQ(result.first, true);
145 ASSERT_EQ(result.second.v, 6);
146
147 result = dl.find('b', "aa");
148 ASSERT_EQ(result.first, true);
149 ASSERT_EQ(result.second.v, 12);
150 }
151
152
TEST_F(FindxTest,NoExactMatch)153 TEST_F(FindxTest, NoExactMatch)
154 {
155 zim::DirentLookup<GetDirentMock> dl(&impl, 4);
156 auto result = dl.find('U', "aa"); // No U namespace => return 10 (the index of the first item from the next namespace)
157 ASSERT_EQ(result.first, false);
158 ASSERT_EQ(result.second.v, 10);
159
160 result = dl.find('A', "aabb"); // aabb is between aaaacc (4) and aabbaa (5) => 5
161 ASSERT_EQ(result.first, false);
162 ASSERT_EQ(result.second.v, 5);
163
164 result = dl.find('A', "aabbb"); // aabbb is between aabbaa (5) and aabbbb (6) => 6
165 ASSERT_EQ(result.first, false);
166 ASSERT_EQ(result.second.v, 6);
167
168 result = dl.find('A', "aabbbc"); // aabbbc is between aabbbb (6) and aabbcc (7) => 7
169 ASSERT_EQ(result.first, false);
170 ASSERT_EQ(result.second.v, 7);
171
172 result = dl.find('A', "bb"); // bb is between aabbcc (7) and cccccc (8) => 8
173 ASSERT_EQ(result.first, false);
174 ASSERT_EQ(result.second.v, 8);
175
176 result = dl.find('A', "dd"); // dd is after cccccc (8) => 9
177 ASSERT_EQ(result.first, false);
178 ASSERT_EQ(result.second.v, 9);
179
180 result = dl.find('M', "f"); // f is before foo (9) => 9
181 ASSERT_EQ(result.first, false);
182 ASSERT_EQ(result.second.v, 9);
183
184 result = dl.find('M', "bar"); // bar is before foo (9) => 9
185 ASSERT_EQ(result.first, false);
186 ASSERT_EQ(result.second.v, 9);
187
188 result = dl.find('M', "foo1"); // foo1 is after foo (9) => 10
189 ASSERT_EQ(result.first, false);
190 ASSERT_EQ(result.second.v, 10);
191 }
192
193
194 } // namespace
195