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