File: Test_CifFile.cpp

package info (click to toggle)
pymol 2.5.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 42,288 kB
  • sloc: cpp: 476,472; python: 76,538; ansic: 29,510; javascript: 6,792; sh: 47; makefile: 24
file content (151 lines) | stat: -rw-r--r-- 5,567 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include "Test.h"

#include "CifFile.h"

using namespace pymol::test;

const char* SAMPLE_CIF_STR = R"""(
data_FOO
_cat1.key1 noquotes
_cat1.key2 "two words"
_cat1.key3 ? # unknown
_cat1.key4 . # inapplicable
_cat1.KEY5 "UPPER CASE key"
loop_
_cat2.key1
_cat2.key2
_cat2.key3
_cat2.key4
10 0.1 . foo
11 0.2 ? "TWO WORDS"
12  ?  ?
;multi
line
value
; . 0.4 . .
data_bar
data_baz
_undotted_key "why not"
_typed_float1 1.23(45)e3
_typed_float2 1.234(5)e1
_typed_float3 1.23456789
)""";

TEST_CASE("misc", "[CifFile]")
{
  // syntax 1
  pymol::cif_file cf1(nullptr, SAMPLE_CIF_STR);
  // syntax 2 (requires move constructor)
  auto cf2 = pymol::cif_file(nullptr, SAMPLE_CIF_STR);
  // move assign
  pymol::cif_file cf3;
  cf3 = pymol::cif_file(nullptr, SAMPLE_CIF_STR);

  // check all three instances have same data
  REQUIRE(cf1.datablocks().size() == 3);
  REQUIRE(cf2.datablocks().size() == 3);
  REQUIRE(cf3.datablocks().size() == 3);
  REQUIRE(cf1.datablocks()[2].get_opt("_undotted_key")->as_s() == std::string("why not"));
  REQUIRE(cf2.datablocks()[2].get_opt("_undotted_key")->as_s() == std::string("why not"));
  REQUIRE(cf3.datablocks()[2].get_opt("_undotted_key")->as_s() == std::string("why not"));

  auto& blocks = cf1.datablocks();

  REQUIRE(blocks[0].code() == std::string("FOO"));
  REQUIRE(blocks[1].code() == std::string("bar"));
  REQUIRE(blocks[2].code() == std::string("baz"));

  auto* data = &blocks.front();

  REQUIRE(data->get_arr("_cat1.key3") != nullptr);
  REQUIRE(data->get_arr("_cat1.key3") == data->get_opt("_cat1.key3"));
  REQUIRE(data->get_arr("_cat1.key6") == nullptr);

  REQUIRE(data->get_opt("_cat1.key1")->is_missing() == false);
  REQUIRE(data->get_opt("_cat1.key2")->is_missing() == false);
  REQUIRE(data->get_opt("_cat1.key3")->is_missing());
  REQUIRE(data->get_opt("_cat1.key4")->is_missing());
  REQUIRE(data->get_opt("_cat1.key5")->is_missing() == false);

  REQUIRE(data->get_opt("_cat1.key4")->is_missing_all());
  REQUIRE(data->get_opt("_cat1.key5")->is_missing_all() == false);

  // looped data

  REQUIRE(data->get_opt("_cat2.key1")->is_missing_all() == false);
  REQUIRE(data->get_opt("_cat2.key3")->is_missing_all());

  // template getters

  std::vector<int> vec1{10, 11, 12, 0};
  std::vector<float> vec2{0.1f, 0.2f, 99.f, 0.4f};

  REQUIRE(data->get_opt("_cat2.key1")->to_vector<int>() == vec1);
  REQUIRE(data->get_opt("_cat2.key2")->to_vector<float>(99.f) == vec2);

  REQUIRE(data->get_opt("_cat2.key4")->as<std::string>(0) == "foo");
  REQUIRE(data->get_opt("_cat2.key4")->as<std::string>(1) == "TWO WORDS");
  REQUIRE(data->get_opt("_cat2.key4")->as<std::string>(2) == "multi\nline\nvalue");
  REQUIRE(data->get_opt("_cat2.key4")->as<std::string>(3) == "");

  REQUIRE(data->get_opt("_cat2.key4")->as<const char*>(0) == std::string("foo"));
  REQUIRE(data->get_opt("_cat2.key4")->as<const char*>(3) == nullptr);

  REQUIRE(data->get_opt("_cat2.key4")->to_vector<const char*>()[0] == std::string("foo"));
  REQUIRE(data->get_opt("_cat2.key4")->to_vector<const char*>()[3] == nullptr);
  REQUIRE(data->get_opt("_cat2.key4")->to_vector<const char*>("ABC")[0] == std::string("foo"));
  REQUIRE(data->get_opt("_cat2.key4")->to_vector<const char*>("ABC")[3] == std::string("ABC"));

  // type deducted from default value

  REQUIRE(data->get_opt("_cat2.key1")->as(0, 99) / 3 == 3); // int
  REQUIRE(data->get_opt("_cat2.key1")->as(0, 99) / 3 != Approx(10. / 3.)); // int
  REQUIRE(data->get_opt("_cat2.key1")->as(0, 99.) / 3 == Approx(10. / 3.)); // double
  REQUIRE(data->get_opt("_cat2.key2")->as(0, 99.) == 0.1);
  REQUIRE(data->get_opt("_cat2.key3")->as(0, 99.f) == 99.f);
  REQUIRE(data->get_opt("_cat2.key4")->as(0, std::string("type deducted")) == "foo");
  REQUIRE(data->get_opt("_cat2.key4")->as(3, std::string("type deducted")) == "type deducted");

  // as_X getters

  REQUIRE(data->get_opt("_cat2.key4")->as_s(0, "ABC") == std::string("foo"));
  REQUIRE(data->get_opt("_cat2.key4")->as_s(3, "ABC") == std::string("ABC")); // missing

  REQUIRE(data->get_opt("_cat2.key1")->as_i(0, 99) == 10);
  REQUIRE(data->get_opt("_cat2.key1")->as_i(1, 99) == 11);
  REQUIRE(data->get_opt("_cat2.key1")->as_i(3, 99) == 99); // missing

  REQUIRE(data->get_opt("_cat2.key1")->as_d(0, 99.) == 10.);
  REQUIRE(data->get_opt("_cat2.key1")->as_d(1, 99.) == 11.);
  REQUIRE(data->get_opt("_cat2.key1")->as_d(3, 99.) == 99.);  // missing

  REQUIRE(data->get_opt("_cat2.key2")->as_d(0, 99.) == 0.1);
  REQUIRE(data->get_opt("_cat2.key2")->as_d(2, 99.) == 99.f); // missing
  REQUIRE(data->get_opt("_cat2.key2")->as_d(3, 99.) == 0.4);

  // out of bounds is default

  REQUIRE(data->get_opt("_cat2.key1")->as_i(50, 99) == 99);

  // alternate names

  REQUIRE(data->get_opt("_cat2.key1", "_other_name")->as_i(0, 99) == 10);
  REQUIRE(data->get_opt("_other_name", "_cat2.key1")->as_i(0, 99) == 10);
  REQUIRE(data->get_opt("_other_name", "_cat2_key1")->as_i(0, 99) == 99);

  // wildcard lookup

  REQUIRE(data->get_arr("_cat2_key1") == nullptr);
  REQUIRE(data->get_opt("_cat2?key1")->as_i(0, 99) == 10);
  REQUIRE(blocks[2].get_arr("_undotted.key") == nullptr);
  REQUIRE(blocks[2].get_opt("_undotted?key")->as_s() == std::string("why not"));

  // float parsing

  REQUIRE(blocks[2].get_opt("_typed_float1")->as<float>() == Approx(1230.f));
  REQUIRE(blocks[2].get_opt("_typed_float1")->as<double>() == Approx(1230.00000));
  REQUIRE(blocks[2].get_opt("_typed_float2")->as<double>() == Approx(12.3400000));
  REQUIRE(blocks[2].get_opt("_typed_float3")->as<double>() == Approx(1.23456789));
}

// vi:sw=2:expandtab