improve pkgTagSection scanning and parsing
[ntk/apt.git] / test / libapt / tagfile_test.cc
1 #include <config.h>
2
3 #include <apt-pkg/fileutl.h>
4 #include <apt-pkg/tagfile.h>
5
6 #include <string>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <unistd.h>
10 #include <sstream>
11
12 #include <gtest/gtest.h>
13
14 #include "file-helpers.h"
15
16 TEST(TagFileTest,SingleField)
17 {
18 FileFd fd;
19 createTemporaryFile("singlefield", fd, NULL, "FieldA-12345678: the value of the field");
20
21 pkgTagFile tfile(&fd);
22 pkgTagSection section;
23 ASSERT_TRUE(tfile.Step(section));
24
25 // It has one field
26 EXPECT_EQ(1, section.Count());
27 // ... and it is called FieldA-12345678
28 EXPECT_TRUE(section.Exists("FieldA-12345678"));
29 // its value is correct
30 EXPECT_EQ("the value of the field", section.FindS("FieldA-12345678"));
31 // A non-existent field has an empty string as value
32 EXPECT_EQ("", section.FindS("FieldB-12345678"));
33 // ... and Exists does not lie about missing fields...
34 EXPECT_FALSE(section.Exists("FieldB-12345678"));
35 // There is only one section in this tag file
36 EXPECT_FALSE(tfile.Step(section));
37 }
38
39 TEST(TagFileTest,MultipleSections)
40 {
41 FileFd fd;
42 createTemporaryFile("bigsection", fd, NULL, "Package: pkgA\n"
43 "Version: 1\n"
44 "Size: 100\n"
45 "Description: aaa\n"
46 " aaa\n"
47 "\n"
48 "Package: pkgB\n"
49 "Version: 1\n"
50 "Flag: no\n"
51 "Description: bbb\n"
52 "\n"
53 "Package: pkgC\n"
54 "Version: 2\n"
55 "Flag: yes\n"
56 "Description:\n"
57 " ccc\n"
58 );
59
60 pkgTagFile tfile(&fd);
61 pkgTagSection section;
62 EXPECT_FALSE(section.Exists("Version"));
63
64 EXPECT_TRUE(tfile.Step(section));
65 EXPECT_EQ(4, section.Count());
66 EXPECT_TRUE(section.Exists("Version"));
67 EXPECT_TRUE(section.Exists("Package"));
68 EXPECT_TRUE(section.Exists("Size"));
69 EXPECT_FALSE(section.Exists("Flag"));
70 EXPECT_TRUE(section.Exists("Description"));
71 EXPECT_EQ("pkgA", section.FindS("Package"));
72 EXPECT_EQ("1", section.FindS("Version"));
73 EXPECT_EQ(1, section.FindULL("Version"));
74 EXPECT_EQ(100, section.FindULL("Size"));
75 unsigned long Flags = 1;
76 EXPECT_TRUE(section.FindFlag("Flag", Flags, 1));
77 EXPECT_EQ(1, Flags);
78 Flags = 0;
79 EXPECT_TRUE(section.FindFlag("Flag", Flags, 1));
80 EXPECT_EQ(0, Flags);
81 EXPECT_EQ("aaa\n aaa", section.FindS("Description"));
82
83
84 EXPECT_TRUE(tfile.Step(section));
85 EXPECT_EQ(4, section.Count());
86 EXPECT_TRUE(section.Exists("Version"));
87 EXPECT_TRUE(section.Exists("Package"));
88 EXPECT_FALSE(section.Exists("Size"));
89 EXPECT_TRUE(section.Exists("Flag"));
90 EXPECT_TRUE(section.Exists("Description"));
91 EXPECT_EQ("pkgB", section.FindS("Package"));
92 EXPECT_EQ("1", section.FindS("Version"));
93 EXPECT_EQ(1, section.FindULL("Version"));
94 EXPECT_EQ(0, section.FindULL("Size"));
95 Flags = 1;
96 EXPECT_TRUE(section.FindFlag("Flag", Flags, 1));
97 EXPECT_EQ(0, Flags);
98 Flags = 0;
99 EXPECT_TRUE(section.FindFlag("Flag", Flags, 1));
100 EXPECT_EQ(0, Flags);
101 EXPECT_EQ("bbb", section.FindS("Description"));
102
103 EXPECT_TRUE(tfile.Step(section));
104 EXPECT_EQ(4, section.Count());
105 EXPECT_TRUE(section.Exists("Version"));
106 EXPECT_TRUE(section.Exists("Package"));
107 EXPECT_FALSE(section.Exists("Size"));
108 EXPECT_TRUE(section.Exists("Flag"));
109 EXPECT_TRUE(section.Exists("Description"));
110 EXPECT_EQ("pkgC", section.FindS("Package"));
111 EXPECT_EQ("2", section.FindS("Version"));
112 EXPECT_EQ(2, section.FindULL("Version"));
113 Flags = 0;
114 EXPECT_TRUE(section.FindFlag("Flag", Flags, 1));
115 EXPECT_EQ(1, Flags);
116 Flags = 1;
117 EXPECT_TRUE(section.FindFlag("Flag", Flags, 1));
118 EXPECT_EQ(1, Flags);
119 EXPECT_EQ("ccc", section.FindS("Description"));
120
121 // There is no section left in this tag file
122 EXPECT_FALSE(tfile.Step(section));
123 }
124
125 TEST(TagFileTest,BigSection)
126 {
127 size_t const count = 500;
128 std::stringstream content;
129 for (size_t i = 0; i < count; ++i)
130 content << "Field-" << i << ": " << (2000 + i) << std::endl;
131
132 FileFd fd;
133 createTemporaryFile("bigsection", fd, NULL, content.str().c_str());
134
135 pkgTagFile tfile(&fd);
136 pkgTagSection section;
137 EXPECT_TRUE(tfile.Step(section));
138
139 EXPECT_EQ(count, section.Count());
140 for (size_t i = 0; i < count; ++i)
141 {
142 std::stringstream name;
143 name << "Field-" << i;
144 EXPECT_TRUE(section.Exists(name.str().c_str())) << name.str() << " does not exist";
145 EXPECT_EQ((2000 + i), section.FindULL(name.str().c_str()));
146 }
147
148 // There is only one section in this tag file
149 EXPECT_FALSE(tfile.Step(section));
150 }
151
152 TEST(TagFileTest, PickedUpFromPreviousCall)
153 {
154 size_t const count = 500;
155 std::stringstream contentstream;
156 for (size_t i = 0; i < count; ++i)
157 contentstream << "Field-" << i << ": " << (2000 + i) << std::endl;
158 contentstream << std::endl << std::endl;
159 std::string content = contentstream.str();
160
161 pkgTagSection section;
162 EXPECT_FALSE(section.Scan(content.c_str(), content.size()/2));
163 EXPECT_NE(0, section.Count());
164 EXPECT_NE(count, section.Count());
165 EXPECT_TRUE(section.Scan(content.c_str(), content.size(), false));
166 EXPECT_EQ(count, section.Count());
167
168 for (size_t i = 0; i < count; ++i)
169 {
170 std::stringstream name;
171 name << "Field-" << i;
172 EXPECT_TRUE(section.Exists(name.str().c_str())) << name.str() << " does not exist";
173 EXPECT_EQ((2000 + i), section.FindULL(name.str().c_str()));
174 }
175 }
176
177 TEST(TagFileTest, SpacesEverywhere)
178 {
179 std::string content =
180 "Package: pkgA\n"
181 "Package: pkgB\n"
182 "NoSpaces:yes\n"
183 "TagSpaces\t :yes\n"
184 "ValueSpaces: \tyes\n"
185 "BothSpaces \t:\t yes\n"
186 "TrailingSpaces: yes\t \n"
187 "Naming Space: yes\n"
188 "Naming Spaces: yes\n"
189 "Package : pkgC \n"
190 "Multi-Colon::yes:\n"
191 "\n\n";
192
193 pkgTagSection section;
194 EXPECT_TRUE(section.Scan(content.c_str(), content.size()));
195 EXPECT_TRUE(section.Exists("Package"));
196 EXPECT_TRUE(section.Exists("NoSpaces"));
197 EXPECT_TRUE(section.Exists("TagSpaces"));
198 EXPECT_TRUE(section.Exists("ValueSpaces"));
199 EXPECT_TRUE(section.Exists("BothSpaces"));
200 EXPECT_TRUE(section.Exists("TrailingSpaces"));
201 EXPECT_TRUE(section.Exists("Naming Space"));
202 EXPECT_TRUE(section.Exists("Naming Spaces"));
203 EXPECT_TRUE(section.Exists("Multi-Colon"));
204 EXPECT_EQ("pkgC", section.FindS("Package"));
205 EXPECT_EQ("yes", section.FindS("NoSpaces"));
206 EXPECT_EQ("yes", section.FindS("TagSpaces"));
207 EXPECT_EQ("yes", section.FindS("ValueSpaces"));
208 EXPECT_EQ("yes", section.FindS("BothSpaces"));
209 EXPECT_EQ("yes", section.FindS("TrailingSpaces"));
210 EXPECT_EQ("yes", section.FindS("Naming Space"));
211 EXPECT_EQ("yes", section.FindS("Naming Spaces"));
212 EXPECT_EQ(":yes:", section.FindS("Multi-Colon"));
213 // overridden values are still present, but not really accessible
214 EXPECT_EQ(11, section.Count());
215 }