parse_document_test.cc
Go to the documentation of this file.
1 // ======================================================================
2 //
3 // test ParameterSet values
4 //
5 // ======================================================================
6 
7 #define BOOST_TEST_MODULE (document test)
8 
9 #include "boost/test/unit_test.hpp"
10 #include "fhiclcpp/ParameterSet.h"
12 #include "fhiclcpp/parse.h"
13 
14 #include <ostream>
15 #include <regex>
16 #include <string>
17 
18 namespace fhicl {
19  std::ostream&
20  boost_test_print_type(std::ostream& os, Protection const protection)
21  {
22  return os << to_string(protection);
23  }
24 }
25 
26 using namespace fhicl;
27 using namespace std;
28 
29 BOOST_AUTO_TEST_SUITE(document_test)
30 
31 BOOST_AUTO_TEST_CASE(empty_document)
32 {
33  std::string document;
34  auto const pset = ParameterSet::make(document);
35  BOOST_TEST(pset.is_empty());
36 }
37 
38 BOOST_AUTO_TEST_CASE(nonempty_document)
39 {
40  std::string document = "a: 1\n"
41  "b: 2\n";
42  auto const pset = ParameterSet::make(document);
43  BOOST_TEST(!pset.is_empty());
44  BOOST_TEST(pset.get<int>("a") == 1);
45  BOOST_TEST(pset.get<int>("b") == 2);
46  BOOST_TEST(pset.get<unsigned>("a") == 1u);
47  BOOST_TEST(pset.get<unsigned>("b") == 2u);
48  BOOST_TEST(pset.get<string>("a") == "1");
49  BOOST_TEST(pset.get<string>("b") == "2");
50 }
51 
52 BOOST_AUTO_TEST_CASE(nested_document)
53 {
54  std::string document = "x.a: 1\n"
55  "x.b: 2\n";
56  auto const tbl = parse_document(document);
57  auto const pset = ParameterSet::make(tbl);
58  BOOST_TEST(!pset.is_empty());
59  BOOST_REQUIRE_NO_THROW(pset.get<ParameterSet>("x"));
60  BOOST_TEST_REQUIRE(!pset.get<ParameterSet>("x").is_empty());
61  BOOST_TEST(pset.get<int>("x.a") == 1);
62  BOOST_TEST(pset.get<int>("x.b") == 2);
63  BOOST_TEST(pset.get<unsigned>("x.a") == 1u);
64  BOOST_TEST(pset.get<unsigned>("x.b") == 2u);
65  BOOST_TEST(pset.get<string>("x.a") == "1");
66  BOOST_TEST(pset.get<string>("x.b") == "2");
67 }
68 
69 BOOST_AUTO_TEST_CASE(badly_nested_document)
70 {
71  std::string document = "{ x.a: 1\n"
72  " x.b: 2\n"
73  "}\n";
74  BOOST_CHECK_THROW(parse_document(document), cet::exception);
75 }
76 
77 BOOST_AUTO_TEST_CASE(overridden_prolog_document)
78 {
79  std::string document = "BEGIN_PROLOG\n"
80  " a: 1\n"
81  " t: { a: 11\n"
82  " b: 12\n"
83  " }\n"
84  "END_PROLOG\n"
85  "a: 2\n"
86  "t.a: @local::t.b\n";
87  auto const pset = ParameterSet::make(document);
88  BOOST_TEST(pset.get<int>("a") == 2);
89  BOOST_REQUIRE_NO_THROW(pset.get<ParameterSet>("t"));
90  BOOST_TEST_REQUIRE(!pset.get<ParameterSet>("t").is_empty());
91  BOOST_TEST(pset.get<int>("t.a") == 12);
92  BOOST_CHECK_THROW(pset.get<int>("t.b"), cet::exception);
93 }
94 
95 BOOST_AUTO_TEST_CASE(contiguous_prolog)
96 {
97  std::string document = "BEGIN_PROLOG\n"
98  " a: 1\n"
99  " t: { a: 11\n"
100  " b: 12\n"
101  " }\n"
102  "END_PROLOG\n"
103  "BEGIN_PROLOG\n"
104  " c: 47\n"
105  "END_PROLOG\n";
106  auto const tbl = parse_document(document);
107  BOOST_TEST(tbl.exists("c"));
108 }
109 
110 BOOST_AUTO_TEST_CASE(noncontiguous_prolog)
111 {
112  std::string document = "BEGIN_PROLOG\n"
113  " a: 1\n"
114  " t: { a: 11\n"
115  " b: 12\n"
116  " }\n"
117  "END_PROLOG\n"
118  "d: 27\n"
119  "BEGIN_PROLOG\n"
120  " c: 47\n"
121  "END_PROLOG\n";
122  BOOST_REQUIRE_THROW(parse_document(document), cet::exception);
123 }
124 
125 BOOST_AUTO_TEST_CASE(overridden_toplevel_document)
126 {
127  std::string document = "a: 1\n"
128  "b: 2\n"
129  "a: 3\n"
130  "c: 4\n"
131  "b: 5\n"
132  "a: 6\n";
133  auto const pset = ParameterSet::make(document);
134  BOOST_TEST(pset.get<int>("a") == 6);
135  BOOST_TEST(pset.get<int>("b") == 5);
136  BOOST_TEST(pset.get<int>("c") == 4);
137 }
138 
139 BOOST_AUTO_TEST_CASE(overridden_nested_document)
140 {
141  std::string document = "t: { a: 1\n"
142  " b: 2\n"
143  " a: 3\n"
144  " c: 4\n"
145  " b: 5\n"
146  " a: 6\n"
147  " }\n";
148  auto const pset = ParameterSet::make(document);
149  BOOST_TEST(pset.get<int>("t.a") == 6);
150  BOOST_TEST(pset.get<int>("t.b") == 5);
151  BOOST_TEST(pset.get<int>("t.c") == 4);
152 }
153 
155 {
156  std::string document = "a: @nil\n"
157  "b: nil\n"
158  "c: \"@nil\"\n"
159  "d: \"nil\"\n"
160  "t: { a: @nil\n"
161  " b: nil\n"
162  " c: \"@nil\"\n"
163  " d: \"nil\"\n"
164  " }\n";
165  auto const pset = ParameterSet::make(document);
166 
167  using nil_t = std::nullptr_t;
168  BOOST_TEST(pset.get<nil_t>("a") == nil_t{});
169  BOOST_TEST(pset.get<nil_t>("t.a") == nil_t{});
170  BOOST_CHECK_THROW(pset.get<string>("a"), fhicl::exception);
171  BOOST_CHECK_THROW(pset.get<double>("a", 14.), fhicl::exception);
172  BOOST_CHECK_THROW(pset.get<string>("t.a"), fhicl::exception);
173  BOOST_CHECK_THROW(pset.get_if_present<string>("a"), fhicl::exception);
174  BOOST_TEST(pset.get<string>("b") == "nil");
175  BOOST_TEST(pset.get<string>("t.b") == "nil");
176  BOOST_TEST(pset.get<string>("c") == "@nil");
177  BOOST_TEST(pset.get<string>("t.c") == "@nil");
178  BOOST_TEST(pset.get<string>("d") == "nil");
179  BOOST_TEST(pset.get<string>("t.d") == "nil");
180 }
181 
183 {
184  std::string document = "BEGIN_PROLOG\n"
185  "x: 27\n"
186  "z: 43\n"
187  "z: @erase\n"
188  "END_PROLOG\n"
189  "a: 27\n"
190  "b: { x: 7 y: 12 }\n"
191  "c: { x: 7 y: 12 x: @erase }\n"
192  "a: @erase\n"
193  "b.x: @erase\n";
194  auto const tbl = parse_document(document);
195  BOOST_TEST(tbl.exists("x"));
196  BOOST_TEST(!tbl.exists("z"));
197  BOOST_TEST(!tbl.exists("a"));
198  BOOST_TEST(tbl.exists("b"));
199  BOOST_TEST(!tbl.exists("b.x"));
200  BOOST_TEST(tbl.exists("b.y"));
201  BOOST_TEST(tbl.exists("c"));
202  BOOST_TEST(!tbl.exists("c.x"));
203  BOOST_TEST(tbl.exists("c.y"));
204 }
205 
206 BOOST_AUTO_TEST_CASE(expand_nested_tables)
207 {
208  std::string document = "BEGIN_PROLOG\n"
209  "A: { B: { x: foo } }\n"
210  "END_PROLOG\n"
211  "modules: {\n"
212  " A: {\n"
213  " @table::A\n"
214  " B:{ @table::A.B x:bar }\n"
215  " }\n"
216  "}\n";
217  auto tbl = parse_document(document);
218  BOOST_TEST(tbl.get<std::string>("modules.A.B.x") == std::string("bar"));
219 }
220 
221 BOOST_AUTO_TEST_CASE(expand_table)
222 {
223  std::string document = "BEGIN_PROLOG\n"
224  "fred: { bill: twelve charlie: 27 }\n"
225  "y: { @table::fred bill: \"one dozen\" }\n"
226  "END_PROLOG\n"
227  "x: { ethel: 14 bill: 12 @table::fred }\n"
228  "@table::fred\n"
229  "y: @local::y\n";
230  auto tbl = parse_document(document);
231  BOOST_TEST(tbl.exists("x.ethel"));
232  BOOST_TEST(tbl.exists("x.charlie"));
233  BOOST_TEST(tbl.exists("bill"));
234  BOOST_TEST(tbl.exists("charlie"));
235  BOOST_TEST(tbl.exists("y.bill"));
236  BOOST_TEST(tbl.exists("y.charlie"));
237  BOOST_TEST(tbl.get<std::string>("x.bill") == std::string("twelve"));
238  BOOST_TEST(tbl.get<std::string>("bill") == std::string("twelve"));
239  BOOST_TEST(tbl.get<std::string>("y.bill") == std::string("one dozen"));
240 }
241 
242 BOOST_AUTO_TEST_CASE(expand_sequence)
243 {
244  std::string document = "BEGIN_PROLOG\n"
245  "fred: [ three, four, five ]\n"
246  "END_PROLOG\n"
247  "bill: [ one, two, @sequence::fred, six ]\n"
248  "charlie: @local::fred\n"
249  "ethel: [ @sequence::fred, six ]\n";
250  auto const tbl = parse_document(document);
251  BOOST_TEST(tbl.exists("fred"));
252  BOOST_TEST(tbl.exists("bill"));
253  BOOST_TEST(tbl.exists("charlie"));
254  BOOST_TEST(tbl.exists("ethel"));
255 
256  auto const pset = ParameterSet::make(tbl);
257 
258  BOOST_TEST(pset.get<std::vector<std::string>>("charlie").size() == 3ul);
259 
260  std::vector<std::string> const billref{
261  "one", "two", "three", "four", "five", "six"};
262  std::vector<std::string> const ethelref{"three", "four", "five", "six"};
263 
264  auto cmp = [](std::vector<std::string> const& seq,
265  std::vector<std::string> const& ref) {
266  BOOST_TEST(seq.size() == ref.size());
267  for (auto i = seq.cbegin(), e = seq.cend(), iref = ref.cbegin(); i != e;
268  ++i, ++iref) {
269  BOOST_TEST(*i == *iref);
270  }
271  };
272 
273  cmp(pset.get<std::vector<std::string>>("bill"), billref);
274  cmp(pset.get<std::vector<std::string>>("ethel"), ethelref);
275 }
276 
277 BOOST_AUTO_TEST_CASE(string_escaping)
278 {
279  BOOST_CHECK_THROW(parse_document(R"(x: "$\d+^")"), cet::exception);
280  BOOST_CHECK_NO_THROW(parse_document(R"(x: "$\\d+^")"));
281  BOOST_CHECK_NO_THROW(parse_document(R"(x: '$\d+^')"));
282 }
283 
285 {
286  std::string document = "x: @local::dead\n";
287  BOOST_CHECK_THROW(parse_document(document), cet::exception);
288 }
289 
290 BOOST_AUTO_TEST_CASE(bad_expand_table)
291 {
292  std::string document = "BEGIN_PROLOG\n"
293  "bad: John\n"
294  "END_PROLOG\n"
295  "@table::bad\n";
296  BOOST_CHECK_THROW(parse_document(document), cet::exception);
297 }
298 
299 BOOST_AUTO_TEST_CASE(bad_expand_sequence)
300 {
301  std::string document = "BEGIN_PROLOG\n"
302  "bad: John\n"
303  "END_PROLOG\n"
304  "f: [ @sequence::bad ]\n";
305  BOOST_CHECK_THROW(parse_document(document), cet::exception);
306 }
307 
308 BOOST_AUTO_TEST_CASE(colon_spacing)
309 {
310  std::string const prolog = "BEGIN_PROLOG\n"
311  "t: { a: 7 b: 6}\n"
312  "s: [ 7, 6, 7 ]\n"
313  "END_PROLOG\n";
314  std::vector<std::string> refs{
315  "t1: @local::t\n",
316  "@table::t\n",
317  "s2: [ 1, 2, @sequence::s ]\n",
318  "a: @id::0001020304050607080910111213141516171819\n",
319  "t1: { t2: @local::t }\n",
320  "t1: { @table::t }\n",
321  "t1: { s1: [ 1, 2, 3, @sequence::s ] }\n",
322  "t1: { a: @id::0001020304050607080910111213141516171819 }\n",
323  };
324  for (auto const& ref : refs) {
325  BOOST_CHECK_NO_THROW(parse_document(prolog + ref));
326  auto const cpos = ref.find("::");
327  BOOST_TEST_REQUIRE(cpos != std::string::npos);
328  std::string bad1{ref};
329  std::string bad2{ref};
330  bad1.insert(cpos, " ");
331  BOOST_CHECK_THROW(parse_document(prolog + bad1), cet::exception);
332  bad2.insert(cpos + 2, " ");
333  BOOST_CHECK_THROW(parse_document(prolog + bad2), cet::exception);
334  }
335 }
336 
337 BOOST_AUTO_TEST_CASE(protect_ignore_01)
338 {
339  std::string const doc = "x @protect_ignore: 29\n"
340  "x: 33\n"
341  "x: 37\n";
342  auto tbl = parse_document(doc);
343  BOOST_TEST(tbl.get<std::size_t>("x") == 29ul);
344 }
345 
346 BOOST_AUTO_TEST_CASE(protect_ignore_02)
347 {
348  std::string const doc = "BEGIN_PROLOG\n"
349  "x @protect_ignore: 29\n"
350  "x: 33\n"
351  "END_PROLOG\n"
352  "x: 37\n";
353  auto tbl = parse_document(doc);
354  BOOST_TEST(tbl.get<std::size_t>("x") == 37ul);
355 }
356 
357 BOOST_AUTO_TEST_CASE(protect_ignore_03)
358 {
359  std::string const doc = "BEGIN_PROLOG\n"
360  "x @protect_ignore: 29\n"
361  "END_PROLOG\n"
362  "x @protect_ignore: 33\n"
363  "x: 37\n";
364  auto tbl = parse_document(doc);
365  BOOST_TEST(tbl.get<std::size_t>("x") == 33ul);
366 }
367 
368 #define PV_EXCEPTION \
369  BOOST_CHECK_EXCEPTION(parse_document(doc), \
370  fhicl::exception, \
371  [](fhicl::exception const& e) -> bool { \
372  return e.categoryCode() == \
373  fhicl::error::parse_error && \
374  e.root_cause() == "Protection violation"; \
375  })
376 
377 BOOST_AUTO_TEST_CASE(protect_ignore_04)
378 {
379  std::string const doc = "x @protect_ignore: 29\n"
380  "x @protect_ignore: 33\n";
381  auto tbl = parse_document(doc);
382  BOOST_TEST(tbl.get<std::size_t>("x") == 29ul);
383 }
384 
385 BOOST_AUTO_TEST_CASE(protect_ignore_05)
386 {
387  std::string const doc = "BEGIN_PROLOG\n"
388  "x @protect_ignore: 29\n"
389  "x @protect_ignore: 33\n"
390  "END_PROLOG\n";
391  auto tbl = parse_document(doc);
392  BOOST_TEST(tbl.get<std::size_t>("x") == 29ul);
393 }
394 
395 BOOST_AUTO_TEST_CASE(protect_ignore_06)
396 {
397  std::string const doc = "a: { x @protect_ignore: 29 }\n"
398  "a.x: 33\n"
399  "a.x: 37\n";
400  auto tbl = parse_document(doc);
401  BOOST_TEST(tbl.get<std::size_t>("a.x") == 29ul);
402 }
403 
404 BOOST_AUTO_TEST_CASE(protect_ignore_07)
405 {
406  std::string const doc = "BEGIN_PROLOG\n"
407  "a: { x @protect_ignore: 29 }\n"
408  "a.x: 33\n"
409  "END_PROLOG\n"
410  "a.x: 37\n";
411  auto tbl = parse_document(doc);
412  BOOST_TEST(tbl.get<std::size_t>("a.x") == 37ul);
413  BOOST_TEST(tbl.find("a.x").protection == fhicl::Protection::NONE);
414 }
415 
416 BOOST_AUTO_TEST_CASE(protect_ignore_08)
417 {
418  std::string const doc = "BEGIN_PROLOG\n"
419  "a: { x @protect_ignore: 29 } \n"
420  "END_PROLOG\n"
421  "a.x @protect_ignore: 33\n"
422  "a.x: 37\n";
423  auto tbl = parse_document(doc);
424  BOOST_TEST(tbl.get<std::size_t>("a.x") == 33ul);
425 }
426 
427 BOOST_AUTO_TEST_CASE(protect_ignore_09)
428 {
429  std::string const doc = "a: { x @protect_ignore: 29 }\n"
430  "a.x @protect_ignore: 33\n";
431  auto tbl = parse_document(doc);
432  BOOST_TEST(tbl.get<std::size_t>("a.x") == 29ul);
433 }
434 
435 BOOST_AUTO_TEST_CASE(protect_ignore_10)
436 {
437  std::string const doc = "BEGIN_PROLOG\n"
438  "a: { x @protect_ignore: 29 }\n"
439  "a.x @protect_ignore: 33\n"
440  "END_PROLOG\n";
441  auto tbl = parse_document(doc);
442  BOOST_TEST(tbl.get<std::size_t>("a.x") == 29ul);
443 }
444 
445 BOOST_AUTO_TEST_CASE(protect_ignore_11)
446 {
447  std::string const doc = "a @protect_ignore: { x: 29 }\n"
448  "a.x: 33\n"
449  "a.x: 37\n";
450  auto tbl = parse_document(doc);
451  BOOST_TEST(tbl.get<std::size_t>("a.x") == 29ul);
452 }
453 
454 BOOST_AUTO_TEST_CASE(protect_ignore_12)
455 {
456  std::string const doc = "BEGIN_PROLOG\n"
457  "a @protect_ignore: { x: 29 }\n"
458  "a.x: 33\n"
459  "END_PROLOG\n"
460  "a.x: 37\n";
461  auto tbl = parse_document(doc);
462  BOOST_TEST(tbl.get<std::size_t>("a.x") == 37ul);
463 }
464 
465 BOOST_AUTO_TEST_CASE(protect_ignore_13)
466 {
467  std::string const doc = "BEGIN_PROLOG\n"
468  "a @protect_ignore: { x: 29 }\n"
469  "END_PROLOG\n"
470  "a @protect_ignore: { x: 33 }\n"
471  "a.x: 37\n";
472  auto tbl = parse_document(doc);
473  BOOST_TEST(tbl.get<std::size_t>("a.x") == 33ul);
474 }
475 
476 BOOST_AUTO_TEST_CASE(protect_ignore_14)
477 {
478  std::string const doc = "a @protect_ignore: { x: 29 }\n"
479  "a @protect_ignore: { x: 33 }\n";
480  auto tbl = parse_document(doc);
481  BOOST_TEST(tbl.get<std::size_t>("a.x") == 29ul);
482 }
483 
484 BOOST_AUTO_TEST_CASE(protect_ignore_15)
485 {
486  std::string const doc = "BEGIN_PROLOG\n"
487  "a @protect_ignore: { x: 29 }\n"
488  "a @protect_ignore: { x: 33 }\n"
489  "END_PROLOG\n";
490  auto tbl = parse_document(doc);
491  BOOST_TEST(tbl.get<std::size_t>("a.x") == 29ul);
492 }
493 
494 BOOST_AUTO_TEST_CASE(protect_ignore_16)
495 {
496  std::string const doc = "a: { b @protect_ignore: { x: 29 } }\n"
497  "a.b.x: 33\n"
498  "a.b.x: 37\n";
499  auto tbl = parse_document(doc);
500  BOOST_TEST(tbl.get<std::size_t>("a.b.x") == 29ul);
501 }
502 
503 BOOST_AUTO_TEST_CASE(protect_ignore_17)
504 {
505  std::string const doc = "BEGIN_PROLOG\n"
506  "a: { b @protect_ignore: { x: 29 } }\n"
507  "a.b.x: 33\n"
508  "END_PROLOG\n"
509  "a: { b @protect_ignore: { x: 37 } }\n"
510  "a.b.x: 41\n";
511  auto tbl = parse_document(doc);
512  BOOST_TEST(tbl.get<std::size_t>("a.b.x") == 37ul);
513 }
514 
515 BOOST_AUTO_TEST_CASE(protect_ignore_18)
516 {
517  std::string const doc = "BEGIN_PROLOG\n"
518  "a: { b @protect_ignore: { x: 29 } }\n"
519  "END_PROLOG\n"
520  "a: { b @protect_ignore: { x: 33 } }\n"
521  "a.b.x: 37\n";
522  auto tbl = parse_document(doc);
523  BOOST_TEST(tbl.get<std::size_t>("a.b.x") == 33ul);
524 }
525 
526 BOOST_AUTO_TEST_CASE(protect_ignore_19)
527 {
528  std::string const doc = "a: { b @protect_ignore: { x: 29 } }\n"
529  "a: { b @protect_ignore: { x: 33 } }\n";
530  auto tbl = parse_document(doc);
531  BOOST_TEST(tbl.get<std::size_t>("a.b.x") == 33ul);
532 }
533 
534 BOOST_AUTO_TEST_CASE(protect_ignore_20)
535 {
536  std::string const doc = "BEGIN_PROLOG\n"
537  "a: { b @protect_ignore: { x: 29 } }\n"
538  "a: { b @protect_ignore: { x: 33 } }\n"
539  "END_PROLOG\n";
540  auto tbl = parse_document(doc);
541  BOOST_TEST(tbl.get<std::size_t>("a.b.x") == 33ul);
542 }
543 
544 BOOST_AUTO_TEST_CASE(protect_ignore_21)
545 {
546  std::string const doc = "a: { x: 29 }\n"
547  "a.x @protect_ignore: 33\n";
548  PV_EXCEPTION;
549 }
550 
551 BOOST_AUTO_TEST_CASE(protect_ignore_22)
552 {
553  std::string const doc = "BEGIN_PROLOG\n"
554  "a: { x: 29 }\n"
555  "a.x @protect_ignore: 33\n"
556  "END_PROLOG\n";
557  PV_EXCEPTION;
558 }
559 
560 BOOST_AUTO_TEST_CASE(protect_ignore_23)
561 {
562  // Even though 'x' is nested inside of 'a', which has a protection
563  // of PROTECT_IGNORE, the protection of 'x' is still NONE.
564  std::string const doc = "a @protect_ignore: { x: 29 }\n"
565  "a.x: 33";
566  auto tbl = parse_document(doc);
567  BOOST_TEST(tbl.get<std::size_t>("a.x") == 29ul);
568  BOOST_TEST(tbl.find("a").protection == Protection::PROTECT_IGNORE);
569  BOOST_TEST(tbl.find("a.x").protection == Protection::NONE);
570 }
571 
572 BOOST_AUTO_TEST_CASE(protect_error_01)
573 {
574  std::string const doc = "BEGIN_PROLOG\n"
575  "x @protect_error: 29\n"
576  "x: 37\n"
577  "END_PROLOG\n";
578  PV_EXCEPTION;
579 }
580 
581 BOOST_AUTO_TEST_CASE(protect_error_02)
582 {
583  std::string const doc = "BEGIN_PROLOG\n"
584  "x @protect_error: 29\n"
585  "END_PROLOG\n"
586  "x: 33\n";
587  auto tbl = parse_document(doc);
588  BOOST_TEST(tbl.get<std::size_t>("x") == 33ul);
589 }
590 
591 BOOST_AUTO_TEST_CASE(protect_error_03)
592 {
593  std::string const doc = "BEGIN_PROLOG\n"
594  "x @protect_error: 29\n"
595  "END_PROLOG\n"
596  "x @protect_error: 33\n"
597  "x: 37\n";
598  PV_EXCEPTION;
599 }
600 
601 BOOST_AUTO_TEST_CASE(protect_error_04)
602 {
603  std::string const doc = "BEGIN_PROLOG\n"
604  "x @protect_ignore: 29\n"
605  "x @protect_error: 33\n"
606  "END_PROLOG\n";
607  PV_EXCEPTION;
608 }
609 
610 BOOST_AUTO_TEST_CASE(protect_error_05)
611 {
612  std::string const doc = "x @protect_ignore: 29\n"
613  "x @protect_error: 33\n";
614  PV_EXCEPTION;
615 }
616 
617 BOOST_AUTO_TEST_CASE(protect_error_06)
618 {
619  std::string const doc = "a: { x @protect_error: 29 }\n"
620  "a: { x @protect_error: 33 }\n";
621  auto tbl = parse_document(doc);
622  BOOST_TEST(tbl.get<std::size_t>("a.x") == 33ul);
623 }
624 
625 BOOST_AUTO_TEST_CASE(protect_error_07)
626 {
627  std::string const doc = "BEGIN_PROLOG\n"
628  "a: { x @protect_error: 29 }\n"
629  "a: { x @protect_error: 33 }\n"
630  "END_PROLOG\n";
631  auto tbl = parse_document(doc);
632  BOOST_TEST(tbl.get<std::size_t>("a.x") == 33ul);
633 }
634 
635 BOOST_AUTO_TEST_CASE(protect_error_08)
636 {
637  std::string const doc = "BEGIN_PROLOG\n"
638  "a: { x @protect_error: 29 }\n"
639  "a.x: 33\n"
640  "END_PROLOG\n";
641  PV_EXCEPTION;
642 }
643 
644 BOOST_AUTO_TEST_CASE(protect_error_09)
645 {
646  std::string const doc = "a: { x @protect_error: 29 }\n"
647  "a.x: 33\n";
648  PV_EXCEPTION;
649 }
650 
651 BOOST_AUTO_TEST_CASE(protect_error_10)
652 {
653  std::string const doc = "BEGIN_PROLOG\n"
654  "a: { b: { x @protect_error: 29 } } \n"
655  "a.b.x: 33\n"
656  "END_PROLOG\n";
657  PV_EXCEPTION;
658 }
659 
660 BOOST_AUTO_TEST_CASE(protect_error_11)
661 {
662  std::string const doc = "BEGIN_PROLOG\n"
663  "a: { b @protect_error: { x: 29 } }\n"
664  "a.b: { x: 33 }\n"
665  "END_PROLOG\n";
666  PV_EXCEPTION;
667 }
668 
670 {
671  std::string const doc = "x: 29\n"
672  "x: @erase";
673  auto const tbl = parse_document(doc);
674  BOOST_TEST(tbl.empty());
675 }
676 
678 {
679  std::string const doc = "BEGIN_PROLOG\n"
680  "x: 29\n"
681  "x: @erase"
682  "END_PROLOG\n";
683  auto const tbl = parse_document(doc);
684  BOOST_TEST(tbl.empty());
685 }
686 
688 {
689  std::string const doc = "x @protect_ignore: 29\n"
690  "x: @erase";
691  auto tbl = parse_document(doc);
692  BOOST_TEST(tbl.get<std::size_t>("x") == 29ul);
693 }
694 
696 {
697  std::string const doc = "x @protect_error: 29\n"
698  "x: @erase";
699  PV_EXCEPTION;
700 }
701 
703 {
704  std::string const doc = "a: { b @protect_ignore: { x: 29 } }\n"
705  "a: @erase\n";
706  auto const tbl = parse_document(doc);
707  BOOST_TEST(tbl.empty());
708 }
709 
711 {
712  std::string const doc = "a: { b @protect_ignore: { x: 29 } }\n"
713  "a.b: @erase\n";
714  auto tbl = parse_document(doc);
715  BOOST_TEST(tbl.get<std::size_t>("a.b.x") == 29ul);
716 }
717 
719 {
720  std::string const doc = "a: { b @protect_ignore: { x: 29 } }\n"
721  "a.b.x: @erase\n";
722  auto tbl = parse_document(doc);
723  BOOST_TEST(tbl.get<std::size_t>("a.b.x") == 29ul);
724 }
725 
727 {
728  std::string const doc = "a: { b @protect_ignore: { c: { x: 29 } } }\n"
729  "a.b.c: @erase\n";
730  auto tbl = parse_document(doc);
731  BOOST_TEST(tbl.get<std::size_t>("a.b.c.x") == 29ul);
732 }
733 
735 {
736  std::string const doc = "a: { b @protect_error: { c: { x: 29 } } }\n"
737  "a.b.c: @erase\n";
738  PV_EXCEPTION;
739 }
740 
742 {
743  std::string const doc = "a: { b @protect_error: { c: { x: 29 } } }\n"
744  "a.b: @erase\n";
745  PV_EXCEPTION;
746 }
747 
749 {
750  std::string const doc = "a: { b @protect_error: { x: 29 } }\n"
751  "a: @erase\n";
752  auto const tbl = parse_document(doc);
753  BOOST_TEST(tbl.empty());
754 }
755 
756 BOOST_AUTO_TEST_CASE(protect_local_01)
757 {
758  std::string const doc = "a @protect_ignore: 42\n"
759  "b: @local::a\n";
760  auto tbl = parse_document(doc);
761  BOOST_TEST(tbl.find("b").protection == Protection::NONE);
762 }
763 
764 BOOST_AUTO_TEST_CASE(protect_local_02)
765 {
766  std::string const doc = "a @protect_error: 42\n"
767  "b: 43\n"
768  "b: @local::a\n";
769  auto tbl = parse_document(doc);
770  BOOST_TEST(tbl.get<std::size_t>("b") == 42ul);
771 }
772 
773 BOOST_AUTO_TEST_CASE(protect_local_03)
774 {
775  std::string const doc = "a @protect_ignore: 42\n"
776  "b: @local::a\n"
777  "b: @erase\n"
778  "b: 43\n";
779  auto tbl = parse_document(doc);
780  BOOST_TEST(tbl.get<std::size_t>("b") == 43ul);
781 }
782 
783 BOOST_AUTO_TEST_CASE(protect_local_04)
784 {
785  std::string const doc = "a @protect_error: 42\n"
786  "b: @local::a\n"
787  "b: 43\n";
788  auto tbl = parse_document(doc);
789  BOOST_TEST(tbl.get<std::size_t>("b") == 43ul);
790 }
791 
792 BOOST_AUTO_TEST_CASE(protect_local_05)
793 {
794  std::string const doc = "BEGIN_PROLOG\n"
795  "x @protect_ignore: 27\n"
796  "a: { b: { x: @local::x } }\n"
797  "END_PROLOG\n"
798  "a: @local::a\n"
799  "a.b.x: 29\n";
800  auto tbl = parse_document(doc);
801  BOOST_TEST(tbl.get<std::size_t>("a.b.x") == 29ul);
802  BOOST_TEST(tbl.find("a.b.x").protection == Protection::NONE);
803 }
804 
805 BOOST_AUTO_TEST_CASE(protect_local_06)
806 {
807  std::string const doc = "BEGIN_PROLOG\n"
808  "x @protect_ignore: 27\n"
809  "a: { b: { x: @local::x } }\n"
810  "END_PROLOG\n"
811  "a @protect_error: @local::a\n"
812  "a.b.x: 29\n";
813  PV_EXCEPTION;
814 }
815 
816 BOOST_AUTO_TEST_CASE(protect_local_07)
817 {
818  std::string const doc = "BEGIN_PROLOG\n"
819  "x @protect_ignore: 27\n"
820  "a: { b: { x: @local::x } }\n"
821  "END_PROLOG\n"
822  "a @protect_ignore: @local::a\n"
823  "a.b.x: 29\n";
824  auto tbl = parse_document(doc);
825  BOOST_TEST(tbl.get<std::size_t>("a.b.x") == 27ul);
826  BOOST_TEST(tbl.find("a.b.x").protection == Protection::NONE);
827  BOOST_TEST(tbl.find("a").protection == Protection::PROTECT_IGNORE);
828 }
829 
830 namespace {
831  bool
832  is_parse_error_at(fhicl::exception const& e, size_t line, size_t charpos)
833  {
834  bool result = e.categoryCode() == fhicl::error::parse_error;
835  if (result) {
836  using std::to_string;
837  static std::regex const RE(
838  "detected at or near line (\\d+), character (\\d+)");
839  std::smatch sm;
840  std::string match_string = e.what();
841  result = std::regex_search(match_string, sm, RE) &&
842  sm[1] == to_string(line) && sm[2] == to_string(charpos);
843  }
844  return result;
845  }
846 }
847 
848 #define PARSE_ERROR(line, charpos) \
849  BOOST_CHECK_EXCEPTION( \
850  parse_document(doc), \
851  fhicl::exception, \
852  std::bind(&is_parse_error_at, std::placeholders::_1, line, charpos));
853 
855 {
856  std::string const doc = "x: 26\n"
857  "a 36\n";
858  PARSE_ERROR(2, 1);
859 }
860 
862 {
863  std::string const doc = "BEGIN_PROLOG\n"
864  "x: 26\n"
865  "a: 36\n"
866  "END_PROLOG\n"
867  "y: 26\n"
868  "b 36\n";
869  PARSE_ERROR(6, 1);
870 }
871 
873 {
874  std::string const doc = "BEGIN_PROLOG\n"
875  "x: 26\n"
876  "a 36\n"
877  "END_PROLOG\n";
878  PARSE_ERROR(3, 1);
879 }
880 
881 BOOST_AUTO_TEST_SUITE_END()
static QCString result
std::string string
Definition: nybbler.cc:12
static ParameterSet make(intermediate_table const &tbl)
Definition: ParameterSet.cc:68
STL namespace.
#define PV_EXCEPTION
BOOST_TEST_REQUIRE(static_cast< bool >(inFile))
std::string to_string(Protection p)
Definition: Protection.cc:4
Protection
Definition: Protection.h:7
const double e
#define PARSE_ERROR(line, charpos)
std::ostream & boost_test_print_type(std::ostream &os, ParameterSet const &pset)
BOOST_AUTO_TEST_CASE(empty_document)
bool is_empty() const
intermediate_table parse_document(std::string const &filename, cet::filepath_maker &maker)
Definition: parse.cc:720
void line(double t, double *p, double &x, double &y, double &z)
Protection protection
QCString doc
std::string to_string(ModuleType const mt)
Definition: ModuleType.h:34
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33