File: test_language.cc

package info (click to toggle)
metkit 1.13.1-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 2,932 kB
  • sloc: cpp: 14,098; sh: 2,532; python: 1,699; ansic: 71; makefile: 18
file content (127 lines) | stat: -rw-r--r-- 4,385 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
/*
 * (C) Copyright 1996- ECMWF.
 *
 * This software is licensed under the terms of the Apache Licence Version 2.0
 * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
 * In applying this licence, ECMWF does not waive the privileges and immunities
 * granted to it by virtue of its status as an intergovernmental organisation nor
 * does it submit to any jurisdiction.
 */


#include <algorithm>
#include <map>
#include <random>
#include <string>
#include <vector>

#include "eckit/testing/Test.h"

#include "metkit/mars/MarsRequest.h"
#include "metkit/mars/Type.h"


namespace metkit::mars::test {

struct Expected {
    const std::string verb;
    std::map<std::string, std::vector<std::string>> keyvalue;
};

using Sequence = std::vector<unsigned long>;

Sequence make_random_sequence(Sequence::value_type min, Sequence::value_type max, Sequence::size_type N) {
    static std::mt19937 gen{std::random_device{}()};
    static std::uniform_int_distribution<Sequence::value_type> dist(min, max);

    Sequence s(N);
    std::generate(s.begin(), s.end(), [&] { return dist(gen); });
    return s;
}

Sequence make_power_sequence(Sequence::value_type min, Sequence::value_type max) {
    Sequence s;
    for (auto i = min; i <= max; i *= 2) {
        s.push_back(i);
    }
    return s;
}

void expect_mars(const std::string& text, const Expected& expected, bool strict = false) {
    auto r = MarsRequest::parse(text, strict);
    EXPECT_EQUAL(expected.verb, r.verb());

    for (const auto& kv : expected.keyvalue) {
        auto v = r.values(kv.first);

        if (kv.first == "grid") {
            EXPECT(kv.second.size() == 1 && v.size() == 1 && v[0] == kv.second[0]);
            continue;
        }

        EXPECT_EQUAL(kv.second, kv.second);
    }
}

// -----------------------------------------------------------------------------

CASE("grid: regular Gaussian grids") {
    const Sequence F{16,  24,  32,  48,  64,  80,  96,   128,  160,  192,  200,  256,  320,
                     400, 512, 576, 640, 800, 912, 1024, 1280, 1600, 2000, 2560, 4000, 8000};

    const auto Fn = [](const auto& other) {
        auto seq = make_random_sequence(2, 8000, 20);
        seq.insert(seq.end(), other.begin(), other.end());
        return seq;
    }(F);

    for (const auto& n : Fn) {
        // known grids are expanded correctly (pattern matching doesn't work reliably here)
        Expected expected{"retrieve", {{"grid", {"F" + std::to_string(n)}}}};
        if (std::find(F.begin(), F.end(), n) == F.end()) {
            expected.keyvalue.clear();
        }

        expect_mars("ret, date=-1, grid=F" + std::to_string(n), expected);
        expect_mars("ret, date=-1, grid=f" + std::to_string(n), expected);
        expect_mars("ret, date=-1, grid=" + std::to_string(n), expected);
    }
}

// -----------------------------------------------------------------------------

CASE("grid: octahedral Gaussian grids") {
    for (const auto& n : make_random_sequence(2, 8000, 20 /*reduced number of tests*/)) {
        const Expected expected{"retrieve", {{"grid", {"O" + std::to_string(n)}}}};
        expect_mars("ret, date=-1, grid=O" + std::to_string(n), expected);
        expect_mars("ret, date=-1, grid=o" + std::to_string(n), expected);
    }
}

// -----------------------------------------------------------------------------

CASE("grid: reduced classical Gaussian grids") {
    for (const auto& n : Sequence{32, 48, 64, 80, 96, 128, 160, 200, 256, 320, 400, 512, 640, 800, 1024, 1280, 8000}) {
        const Expected expected{"retrieve", {{"grid", {"N" + std::to_string(n)}}}};
        expect_mars("ret, date=-1, grid=N" + std::to_string(n), expected);
        expect_mars("ret, date=-1, grid=n" + std::to_string(n), expected);
    }
}

// -----------------------------------------------------------------------------

CASE("grid: HEALPix grids") {
    for (const auto& n : make_power_sequence(2, 8192)) {
        const Expected expected{"retrieve", {{"grid", {"H" + std::to_string(n)}}}};
        expect_mars("ret, date=-1, grid=H" + std::to_string(n), expected);
        expect_mars("ret, date=-1, grid=h" + std::to_string(n), expected);
    }
}

// -----------------------------------------------------------------------------

}  // namespace metkit::mars::test

int main(int argc, char** argv) {
    return eckit::testing::run_tests(argc, argv);
}