Line data Source code
1 : /**
2 : * @file
3 : *
4 : * @brief Tests for the spec readerclass
5 : *
6 : * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
7 : *
8 : */
9 :
10 : #define ELEKTRA_PLUGINSPEC_WITH_COMPARE
11 :
12 : #include <specreader.hpp>
13 :
14 : #include <algorithm>
15 : #include <iostream>
16 : #include <string>
17 : #include <unordered_map>
18 :
19 : #include <gtest/gtest.h>
20 : #include <kdb.hpp>
21 :
22 20 : TEST (SpecReader, withDatabase)
23 : {
24 : using namespace kdb;
25 : using namespace kdb::tools;
26 2 : std::shared_ptr<MockPluginDatabase> mpd = std::make_shared<MockPluginDatabase> ();
27 24 : mpd->data[PluginSpec ("a")]["ordering"] = "d";
28 24 : mpd->data[PluginSpec ("b")]["ordering"] = "d";
29 22 : mpd->data[PluginSpec ("c")]["ordering"];
30 6 : BackendBuilderInit mpi (mpd);
31 4 : SpecReader sr (mpi);
32 12 : sr.readSpecification (KeySet (5, *Key ("spec", KEY_END), *Key ("spec/mp", KEY_META, "mountpoint", "file.ini", KEY_END),
33 6 : *Key ("spec/mp/below", KEY_META, "config/needs/something", "here", KEY_END), KS_END));
34 14 : SpecBackendBuilder bi = sr.getBackends ()[Key ("spec/mp", KEY_END)];
35 6 : EXPECT_EQ (bi.nodes, 2);
36 8 : EXPECT_EQ (bi.getMountpoint (), "/mp");
37 8 : EXPECT_EQ (bi.getConfigFile (), "file.ini");
38 14 : EXPECT_EQ (bi.getBackendConfig (), KeySet (5, *Key ("user/something", KEY_VALUE, "here", KEY_END), KS_END));
39 6 : EXPECT_FALSE (bi.validated ());
40 12 : ASSERT_EQ (std::distance (bi.begin (), bi.end ()), 0) << "there should be no plugin added";
41 : }
42 :
43 20 : TEST (SpecReader, withDatabaseRecursive)
44 : {
45 : using namespace kdb;
46 : using namespace kdb::tools;
47 2 : std::shared_ptr<MockPluginDatabase> mpd = std::make_shared<MockPluginDatabase> ();
48 24 : mpd->data[PluginSpec ("a")]["ordering"] = "d";
49 24 : mpd->data[PluginSpec ("b")]["ordering"] = "d";
50 22 : mpd->data[PluginSpec ("c")]["ordering"];
51 6 : BackendBuilderInit mpi (mpd);
52 4 : SpecReader sr (mpi);
53 14 : sr.readSpecification (KeySet (5, *Key ("spec", KEY_END), *Key ("spec/mp", KEY_META, "mountpoint", "file.ini", KEY_END),
54 4 : *Key ("spec/mp/below", KEY_META, "config/needs/something", "else", KEY_END),
55 6 : *Key ("spec/mp/below/recursive", KEY_META, "mountpoint", "otherfile.ini", KEY_END), KS_END));
56 14 : SpecBackendBuilder bi = sr.getBackends ()[Key ("spec/mp", KEY_END)];
57 6 : EXPECT_EQ (bi.nodes, 2);
58 2 : }
59 :
60 20 : TEST (SpecReader, withNeeds)
61 : {
62 : using namespace kdb;
63 : using namespace kdb::tools;
64 2 : std::shared_ptr<MockPluginDatabase> mpd = std::make_shared<MockPluginDatabase> ();
65 24 : mpd->data[PluginSpec ("a")]["provides"] = "resolver";
66 24 : mpd->data[PluginSpec ("b")]["provides"] = "storage";
67 6 : BackendBuilderInit mpi (mpd);
68 4 : SpecReader sr (mpi);
69 8 : sr.readSpecification (KeySet (
70 8 : 5, *Key ("spec", KEY_END), *Key ("spec/mp", KEY_META, "mountpoint", "file.ini", KEY_END),
71 4 : *Key ("spec/mp/below", KEY_META, "config/needs/something", "here", KEY_META, "infos/needs", "resolver storage", KEY_END),
72 2 : KS_END));
73 12 : SpecBackendBuilder bi = sr.getBackends ()[Key ("spec/mp", KEY_END)];
74 6 : EXPECT_EQ (bi.nodes, 2);
75 8 : EXPECT_EQ (bi.getMountpoint (), "/mp");
76 8 : EXPECT_EQ (bi.getConfigFile (), "file.ini");
77 14 : EXPECT_EQ (bi.getBackendConfig (), KeySet (5, *Key ("user/something", KEY_VALUE, "here", KEY_END), KS_END));
78 6 : EXPECT_FALSE (bi.validated ());
79 12 : ASSERT_EQ (std::distance (bi.begin (), bi.end ()), 0);
80 2 : bi.resolveNeeds ();
81 12 : ASSERT_EQ (std::distance (bi.begin (), bi.end ()), 2) << "there should be a resolver and storage added";
82 22 : EXPECT_EQ (bi.begin ()[0], PluginSpec ("a", "resolver"));
83 24 : EXPECT_EQ (bi.begin ()[1], PluginSpec ("b", "storage"));
84 : }
85 :
86 20 : TEST (SpecReader, withNeedsResolved)
87 : {
88 : using namespace kdb;
89 : using namespace kdb::tools;
90 2 : std::shared_ptr<MockPluginDatabase> mpd = std::make_shared<MockPluginDatabase> ();
91 24 : mpd->data[PluginSpec ("a")]["provides"] = "storage";
92 24 : mpd->data[PluginSpec ("b")]["provides"] = "resolver";
93 4 : BackendBuilderInit mpi (mpd);
94 4 : SpecReader sr (mpi);
95 : // clang-format off
96 8 : sr.readSpecification(KeySet(5,
97 4 : *Key ("spec", KEY_END),
98 4 : *Key ("spec/mp", KEY_META, "mountpoint", "file.ini",
99 : KEY_META, "config/needs/something", "here",
100 : KEY_META, "infos/needs", "resolver storage",
101 : KEY_END),
102 4 : *Key ("spec/mp/below",
103 : KEY_META, "config/needs/else", "too",
104 : KEY_META, "infos/needs", "a b",
105 : KEY_END),
106 2 : KS_END));
107 : // clang-format on
108 14 : SpecBackendBuilder bi = sr.getBackends ()[Key ("spec/mp", KEY_END)];
109 6 : EXPECT_EQ (bi.nodes, 2);
110 8 : EXPECT_EQ (bi.getMountpoint (), "/mp");
111 8 : EXPECT_EQ (bi.getConfigFile (), "file.ini");
112 18 : EXPECT_EQ (bi.getBackendConfig (),
113 0 : KeySet (5, *Key ("user/something", KEY_VALUE, "here", KEY_END), *Key ("user/else", KEY_VALUE, "too", KEY_END), KS_END));
114 2 : bi.resolveNeeds ();
115 12 : ASSERT_EQ (std::distance (bi.begin (), bi.end ()), 2) << "there should be a resolver and storage added";
116 22 : EXPECT_EQ (bi.begin ()[0], PluginSpec ("b", "resolver"));
117 24 : EXPECT_EQ (bi.begin ()[1], PluginSpec ("a", "storage"));
118 : }
119 :
120 20 : TEST (SpecReader, withNeedsResolvedPreferences)
121 : {
122 : using namespace kdb;
123 : using namespace kdb::tools;
124 2 : std::shared_ptr<MockPluginDatabase> mpd = std::make_shared<MockPluginDatabase> ();
125 24 : mpd->data[PluginSpec ("a")]["provides"] = "storage";
126 24 : mpd->data[PluginSpec ("a")]["status"] = "productive";
127 :
128 24 : mpd->data[PluginSpec ("b")]["provides"] = "storage";
129 24 : mpd->data[PluginSpec ("b")]["status"] = "productive memleak";
130 :
131 20 : mpd->data[PluginSpec ("c")]["provides"] = "storage";
132 24 : mpd->data[PluginSpec ("c")]["status"] = "productive tested";
133 :
134 24 : mpd->data[PluginSpec ("r")]["provides"] = "resolver";
135 6 : BackendBuilderInit mpi (mpd);
136 4 : SpecReader sr (mpi);
137 : // clang-format off
138 8 : sr.readSpecification(KeySet(5,
139 4 : *Key ("spec", KEY_END),
140 4 : *Key ("spec/mp", KEY_META, "mountpoint", "file.ini",
141 : KEY_META, "infos/needs", "resolver storage",
142 : KEY_END),
143 4 : *Key ("spec/mp/below",
144 : KEY_END),
145 2 : KS_END));
146 : // clang-format on
147 14 : SpecBackendBuilder bi = sr.getBackends ()[Key ("spec/mp", KEY_END)];
148 6 : EXPECT_EQ (bi.nodes, 2);
149 8 : EXPECT_EQ (bi.getMountpoint (), "/mp");
150 8 : EXPECT_EQ (bi.getConfigFile (), "file.ini");
151 2 : bi.resolveNeeds ();
152 12 : ASSERT_EQ (std::distance (bi.begin (), bi.end ()), 2) << "there should be a resolver and storage added";
153 22 : EXPECT_EQ (bi.begin ()[0], PluginSpec ("r", "resolver"));
154 24 : EXPECT_EQ (bi.begin ()[1], PluginSpec ("c", "storage"));
155 : }
156 :
157 20 : TEST (SpecReader, withNeedsResolvedPreferencesPlugins)
158 : {
159 : using namespace kdb;
160 : using namespace kdb::tools;
161 2 : std::shared_ptr<MockPluginDatabase> mpd = std::make_shared<MockPluginDatabase> ();
162 24 : mpd->data[PluginSpec ("a")]["provides"] = "storage";
163 24 : mpd->data[PluginSpec ("a")]["status"] = "productive";
164 :
165 24 : mpd->data[PluginSpec ("b")]["provides"] = "storage";
166 24 : mpd->data[PluginSpec ("b")]["status"] = "productive memleak";
167 :
168 24 : mpd->data[PluginSpec ("c")]["provides"] = "storage";
169 24 : mpd->data[PluginSpec ("c")]["status"] = "productive tested";
170 :
171 24 : mpd->data[PluginSpec ("r")]["provides"] = "resolver";
172 6 : BackendBuilderInit mpi (mpd);
173 4 : SpecReader sr (mpi);
174 : // clang-format off
175 8 : sr.readSpecification(KeySet(5,
176 4 : *Key ("spec", KEY_END),
177 4 : *Key ("spec/mp", KEY_META, "mountpoint", "file.ini",
178 : KEY_META, "infos/plugins", "b",
179 : KEY_META, "infos/needs", "resolver storage",
180 : KEY_END),
181 4 : *Key ("spec/mp/below",
182 : KEY_END),
183 2 : KS_END));
184 : // clang-format on
185 14 : SpecBackendBuilder bi = sr.getBackends ()[Key ("spec/mp", KEY_END)];
186 6 : EXPECT_EQ (bi.nodes, 2);
187 8 : EXPECT_EQ (bi.getMountpoint (), "/mp");
188 8 : EXPECT_EQ (bi.getConfigFile (), "file.ini");
189 12 : ASSERT_EQ (std::distance (bi.begin (), bi.end ()), 1) << "there should be nothing added";
190 22 : EXPECT_EQ (bi.begin ()[0], PluginSpec ("b", "b"));
191 2 : bi.resolveNeeds ();
192 12 : ASSERT_EQ (std::distance (bi.begin (), bi.end ()), 2) << "there should be a resolver and storage added";
193 22 : EXPECT_EQ (bi.begin ()[0], PluginSpec ("b", "b"));
194 24 : EXPECT_EQ (bi.begin ()[1], PluginSpec ("r", "resolver"));
195 : }
196 :
197 20 : TEST (SpecReader, withNeedsResolvedNumerical)
198 : {
199 : using namespace kdb;
200 : using namespace kdb::tools;
201 2 : std::shared_ptr<MockPluginDatabase> mpd = std::make_shared<MockPluginDatabase> ();
202 24 : mpd->data[PluginSpec ("a")]["provides"] = "storage";
203 24 : mpd->data[PluginSpec ("a")]["status"] = "productive";
204 :
205 24 : mpd->data[PluginSpec ("b")]["provides"] = "storage";
206 24 : mpd->data[PluginSpec ("b")]["status"] = "productive memleak 501";
207 :
208 24 : mpd->data[PluginSpec ("c")]["provides"] = "storage";
209 24 : mpd->data[PluginSpec ("c")]["status"] = "productive tested";
210 :
211 24 : mpd->data[PluginSpec ("r")]["provides"] = "resolver";
212 6 : BackendBuilderInit mpi (mpd);
213 4 : SpecReader sr (mpi);
214 : sr.readSpecification (
215 10 : KeySet (5, *Key ("spec", KEY_END),
216 4 : *Key ("spec/mp", KEY_META, "mountpoint", "file.ini", KEY_META, "infos/needs", "resolver storage", KEY_END),
217 6 : *Key ("spec/mp/below", KEY_END), KS_END));
218 14 : SpecBackendBuilder bi = sr.getBackends ()[Key ("spec/mp", KEY_END)];
219 6 : EXPECT_EQ (bi.nodes, 2);
220 8 : EXPECT_EQ (bi.getMountpoint (), "/mp");
221 8 : EXPECT_EQ (bi.getConfigFile (), "file.ini");
222 2 : bi.resolveNeeds ();
223 12 : ASSERT_EQ (std::distance (bi.begin (), bi.end ()), 2) << "there should be a resolver and storage added";
224 22 : EXPECT_EQ (bi.begin ()[0], PluginSpec ("r", "resolver"));
225 24 : EXPECT_EQ (bi.begin ()[1], PluginSpec ("c", "storage"));
226 : }
227 :
228 :
229 20 : TEST (SpecReader, withNeedsResolvedPreferencesIgnored)
230 : {
231 : using namespace kdb;
232 : using namespace kdb::tools;
233 2 : std::shared_ptr<MockPluginDatabase> mpd = std::make_shared<MockPluginDatabase> ();
234 24 : mpd->data[PluginSpec ("a")]["provides"] = "storage";
235 24 : mpd->data[PluginSpec ("a")]["status"] = "productive";
236 :
237 24 : mpd->data[PluginSpec ("b")]["provides"] = "storage";
238 24 : mpd->data[PluginSpec ("b")]["status"] = "productive memleak";
239 :
240 24 : mpd->data[PluginSpec ("c")]["provides"] = "storage";
241 24 : mpd->data[PluginSpec ("c")]["status"] = "productive tested";
242 :
243 24 : mpd->data[PluginSpec ("r")]["provides"] = "resolver";
244 6 : BackendBuilderInit mpi (mpd);
245 4 : SpecReader sr (mpi);
246 : // clang-format off
247 8 : sr.readSpecification(KeySet(5,
248 4 : *Key ("spec", KEY_END),
249 4 : *Key ("spec/mp", KEY_META, "mountpoint", "file.ini",
250 : KEY_META, "infos/needs", "a", // warning: order matters here..
251 : KEY_END),
252 4 : *Key ("spec/mp/below",
253 : KEY_META, "infos/needs", "resolver storage",
254 : KEY_END),
255 2 : KS_END));
256 : // clang-format on
257 14 : SpecBackendBuilder bi = sr.getBackends ()[Key ("spec/mp", KEY_END)];
258 6 : EXPECT_EQ (bi.nodes, 2);
259 8 : EXPECT_EQ (bi.getMountpoint (), "/mp");
260 8 : EXPECT_EQ (bi.getConfigFile (), "file.ini");
261 2 : bi.resolveNeeds ();
262 12 : ASSERT_EQ (std::distance (bi.begin (), bi.end ()), 2) << "there should be a resolver and storage added";
263 16 : EXPECT_EQ (bi.begin ()[0], PluginSpec ("a"));
264 24 : EXPECT_EQ (bi.begin ()[1], PluginSpec ("r", "resolver"));
265 : }
266 :
267 20 : TEST (SpecReader, withMetadata)
268 : {
269 : using namespace kdb;
270 : using namespace kdb::tools;
271 2 : std::shared_ptr<MockPluginDatabase> mpd = std::make_shared<MockPluginDatabase> ();
272 24 : mpd->data[PluginSpec ("rename")]["metadata"] = "rename/toupper rename/tolower";
273 24 : mpd->data[PluginSpec ("mathcheck")]["metadata"] = "check/math";
274 6 : BackendBuilderInit mpi (mpd);
275 4 : SpecReader sr (mpi);
276 : // clang-format off
277 8 : sr.readSpecification(KeySet(5,
278 4 : *Key ("spec", KEY_END),
279 4 : *Key ("spec/mp", KEY_META, "mountpoint", "file.ini",
280 : KEY_META, "rename/toupper", "2",
281 : KEY_END),
282 4 : *Key ("spec/mp/below",
283 : KEY_META, "default", "5",
284 : KEY_META, "check/math", "below >= 3",
285 : KEY_END),
286 2 : KS_END));
287 : // clang-format on
288 14 : SpecBackendBuilder bi = sr.getBackends ()[Key ("spec/mp", KEY_END)];
289 6 : EXPECT_EQ (bi.nodes, 2);
290 8 : EXPECT_EQ (bi.getMountpoint (), "/mp");
291 8 : EXPECT_EQ (bi.getConfigFile (), "file.ini");
292 2 : bi.resolveNeeds ();
293 12 : ASSERT_EQ (std::distance (bi.begin (), bi.end ()), 2) << "there should be plugins added";
294 16 : EXPECT_EQ (bi.begin ()[0], PluginSpec ("mathcheck"));
295 18 : EXPECT_EQ (bi.begin ()[1], PluginSpec ("rename"));
296 : }
297 :
298 :
299 20 : TEST (SpecReader, withMetadataPreference)
300 : {
301 : using namespace kdb;
302 : using namespace kdb::tools;
303 2 : std::shared_ptr<MockPluginDatabase> mpd = std::make_shared<MockPluginDatabase> ();
304 24 : mpd->data[PluginSpec ("mathcheck")]["metadata"] = "check/math";
305 24 : mpd->data[PluginSpec ("mathcheck")]["status"] = "concept unfinished";
306 24 : mpd->data[PluginSpec ("fastcheck")]["metadata"] = "check/math";
307 24 : mpd->data[PluginSpec ("fastcheck")]["status"] = "recommended preview";
308 24 : mpd->data[PluginSpec ("bestcheck")]["metadata"] = "check/math";
309 24 : mpd->data[PluginSpec ("bestcheck")]["status"] = "recommended";
310 6 : BackendBuilderInit mpi (mpd);
311 4 : SpecReader sr (mpi);
312 12 : sr.readSpecification (KeySet (5, *Key ("spec", KEY_END), *Key ("spec/mp", KEY_META, "mountpoint", "file.ini", KEY_END),
313 6 : *Key ("spec/mp/below", KEY_META, "check/math", "below >= 3", KEY_END), KS_END));
314 14 : SpecBackendBuilder bi = sr.getBackends ()[Key ("spec/mp", KEY_END)];
315 6 : EXPECT_EQ (bi.nodes, 2);
316 8 : EXPECT_EQ (bi.getMountpoint (), "/mp");
317 8 : EXPECT_EQ (bi.getConfigFile (), "file.ini");
318 2 : bi.resolveNeeds ();
319 12 : ASSERT_EQ (std::distance (bi.begin (), bi.end ()), 1) << "there should be plugins added";
320 16 : EXPECT_EQ (bi.begin ()[0], PluginSpec ("bestcheck"));
321 : }
322 :
323 :
324 20 : TEST (SpecReader, withMetadataPreferenceNumerical)
325 : {
326 : using namespace kdb;
327 : using namespace kdb::tools;
328 12 : EXPECT_EQ (PluginDatabase::calculateStatus ("WRONG -5"), -5);
329 12 : EXPECT_EQ (PluginDatabase::calculateStatus ("-5 WRONG"), -5);
330 12 : EXPECT_EQ (PluginDatabase::calculateStatus ("5 WRONG"), 5);
331 12 : EXPECT_EQ (PluginDatabase::calculateStatus ("WRONG 5"), 5);
332 :
333 2 : std::shared_ptr<MockPluginDatabase> mpd = std::make_shared<MockPluginDatabase> ();
334 24 : mpd->data[PluginSpec ("mathcheck")]["metadata"] = "check/math";
335 24 : mpd->data[PluginSpec ("mathcheck")]["status"] = "popular -5";
336 24 : mpd->data[PluginSpec ("fastcheck")]["metadata"] = "check/math";
337 24 : mpd->data[PluginSpec ("fastcheck")]["status"] = "popular";
338 24 : mpd->data[PluginSpec ("bestcheck")]["metadata"] = "check/math";
339 24 : mpd->data[PluginSpec ("bestcheck")]["status"] = "popular 5";
340 6 : BackendBuilderInit mpi (mpd);
341 4 : SpecReader sr (mpi);
342 12 : sr.readSpecification (KeySet (5, *Key ("spec", KEY_END), *Key ("spec/mp", KEY_META, "mountpoint", "file.ini", KEY_END),
343 6 : *Key ("spec/mp/below", KEY_META, "check/math", "below >= 3", KEY_END), KS_END));
344 14 : SpecBackendBuilder bi = sr.getBackends ()[Key ("spec/mp", KEY_END)];
345 6 : EXPECT_EQ (bi.nodes, 2);
346 8 : EXPECT_EQ (bi.getMountpoint (), "/mp");
347 8 : EXPECT_EQ (bi.getConfigFile (), "file.ini");
348 2 : bi.resolveNeeds ();
349 12 : ASSERT_EQ (std::distance (bi.begin (), bi.end ()), 1) << "there should be plugins added";
350 16 : EXPECT_EQ (bi.begin ()[0], PluginSpec ("bestcheck"));
351 : }
352 :
353 20 : TEST (SpecReader, pluginConfiguration)
354 : {
355 : using namespace kdb;
356 : using namespace kdb::tools;
357 2 : std::shared_ptr<MockPluginDatabase> mpd = std::make_shared<MockPluginDatabase> ();
358 24 : mpd->data[PluginSpec ("python#transform")]["provides"] = "transform";
359 24 : mpd->data[PluginSpec ("python#transform")]["metadata"] = "transform/python";
360 24 : mpd->data[PluginSpec ("python#transform")]["status"] = "memleak";
361 : // twice python does not work because of limitation in MockPluginDatabase (does not use ref)
362 24 : mpd->data[PluginSpec ("lua#rename")]["provides"] = "rename";
363 24 : mpd->data[PluginSpec ("lua#rename")]["metadata"] = "rename/toupper rename/tolower";
364 24 : mpd->data[PluginSpec ("lua#rename")]["status"] = "memleak";
365 6 : BackendBuilderInit mpi (mpd);
366 4 : SpecReader sr (mpi);
367 : // clang-format off
368 10 : sr.readSpecification(KeySet(5,
369 4 : *Key ("spec", KEY_END),
370 4 : *Key ("spec/mp", KEY_META, "mountpoint", "file.ini",
371 : KEY_END),
372 4 : *Key ("spec/mp/transform",
373 : KEY_META, "infos/plugins", "python#transform script=transform.py",
374 : KEY_META, "transform/python", "below = other+5",
375 : KEY_END),
376 4 : *Key ("spec/mp/rename",
377 : KEY_META, "infos/plugins", "lua#rename norename=,script=rename.lua",
378 : KEY_META, "rename/toupper", "1",
379 : KEY_END),
380 2 : KS_END));
381 : // clang-format on
382 14 : SpecBackendBuilder bi = sr.getBackends ()[Key ("spec/mp", KEY_END)];
383 6 : EXPECT_EQ (bi.nodes, 3);
384 8 : EXPECT_EQ (bi.getMountpoint (), "/mp");
385 8 : EXPECT_EQ (bi.getConfigFile (), "file.ini");
386 12 : ASSERT_EQ (std::distance (bi.begin (), bi.end ()), 2) << "there should be plugins added";
387 24 : EXPECT_EQ (bi.begin ()[0], PluginSpec ("lua#rename", KeySet (2, *Key ("user/script", KEY_VALUE, "rename.lua", KEY_END),
388 0 : *Key ("user/norename", KEY_END), KS_END)));
389 22 : EXPECT_EQ (bi.begin ()[1],
390 0 : PluginSpec ("python#transform", KeySet (1, *Key ("user/script", KEY_VALUE, "transform.py", KEY_END), KS_END)));
391 2 : bi.resolveNeeds ();
392 12 : ASSERT_EQ (std::distance (bi.begin (), bi.end ()), 2) << "there should be plugins added";
393 24 : EXPECT_EQ (bi.begin ()[0], PluginSpec ("lua#rename", KeySet (2, *Key ("user/script", KEY_VALUE, "rename.lua", KEY_END),
394 0 : *Key ("user/norename", KEY_END), KS_END)));
395 22 : EXPECT_EQ (bi.begin ()[1],
396 0 : PluginSpec ("python#transform", KeySet (1, *Key ("user/script", KEY_VALUE, "transform.py", KEY_END), KS_END)));
397 6 : }
|