|
10 | 10 | /// |
11 | 11 | //===----------------------------------------------------------------------===// |
12 | 12 |
|
| 13 | +#include <iterator> |
13 | 14 | #include <limits> |
| 15 | +#include <set> |
| 16 | +#include <string> |
14 | 17 | #include <gtest/gtest.h> |
15 | 18 | #include "grtest_api_fixture.hpp" |
16 | 19 |
|
@@ -47,3 +50,112 @@ TEST_F(SimpleRateQueryTest, PtrInvalidRateId) { |
47 | 50 | grunstable_ratequery_get_ptr(pack.my_rates(), get_invalid_rateid(pack)); |
48 | 51 | EXPECT_EQ(ptr, nullptr); |
49 | 52 | } |
| 53 | + |
| 54 | +// will be implemented (in a much more robust manner) in the near future |
| 55 | +unsigned long long grunstable_ratequery_nrates( |
| 56 | + const chemistry_data_storage* my_rates) { |
| 57 | + // current implementation is stupid! (in future, will use my_rates) |
| 58 | + unsigned long long i = 0; |
| 59 | + while (nullptr != grunstable_ith_rate(i, nullptr)) { |
| 60 | + i++; |
| 61 | + } |
| 62 | + return i; |
| 63 | +} |
| 64 | + |
| 65 | +// most of the remaining tests (and future planned tests) involve iterating |
| 66 | +// through all rates made available via the ratequery interface. To make the |
| 67 | +// tests themselves as easy to read as possible, we implate a C++-style |
| 68 | +// iterator to wrap part of the interface |
| 69 | + |
| 70 | +struct RateNameIdPair { |
| 71 | + std::string name; |
| 72 | + grunstable_rateid_type rateid; |
| 73 | +}; |
| 74 | + |
| 75 | +class RQIterator { |
| 76 | + chemistry_data_storage* my_rates_; |
| 77 | + unsigned long long counter_; |
| 78 | + unsigned long long n_rates_; |
| 79 | + RateNameIdPair pair_; |
| 80 | + |
| 81 | + RQIterator& update_pair_and_ret_(unsigned long long val) { |
| 82 | + if (val < n_rates_) { |
| 83 | + pair_.name = std::string(grunstable_ith_rate(val, &pair_.rateid)); |
| 84 | + } |
| 85 | + return *this; |
| 86 | + } |
| 87 | + |
| 88 | +public: |
| 89 | + using iterator_category = std::input_iterator_tag; |
| 90 | + using value_type = RateNameIdPair; |
| 91 | + using difference_type = std::ptrdiff_t; |
| 92 | + using pointer = const RateNameIdPair*; |
| 93 | + using reference = const RateNameIdPair; |
| 94 | + |
| 95 | + RQIterator(unsigned long long counter, unsigned long long n_rates, |
| 96 | + chemistry_data_storage* my_rates) |
| 97 | + : my_rates_(my_rates), counter_(counter), n_rates_(n_rates) { |
| 98 | + update_pair_and_ret_(counter); |
| 99 | + } |
| 100 | + |
| 101 | + bool operator==(RQIterator other) const { |
| 102 | + return (counter_ == other.counter_) && (my_rates_ == other.my_rates_); |
| 103 | + } |
| 104 | + |
| 105 | + bool operator!=(RQIterator other) const { return !(*this == other); } |
| 106 | + reference operator*() const { return pair_; } |
| 107 | + RQIterator& operator++() { return update_pair_and_ret_(++counter_); } |
| 108 | + |
| 109 | + RQIterator operator++(int) { |
| 110 | + RQIterator ret = *this; |
| 111 | + ++(*this); |
| 112 | + return ret; |
| 113 | + } |
| 114 | +}; |
| 115 | + |
| 116 | +// used for creating the iterator and within range-based for-loops |
| 117 | +class RateQueryRange { |
| 118 | + grtest::GrackleCtxPack& pack_; |
| 119 | + long long n_rates_; |
| 120 | + |
| 121 | +public: |
| 122 | + explicit RateQueryRange(grtest::GrackleCtxPack& pack) |
| 123 | + : pack_(pack), n_rates_(grunstable_ratequery_nrates(pack.my_rates())) {} |
| 124 | + |
| 125 | + RQIterator begin() { return RQIterator(0, n_rates_, pack_.my_rates()); } |
| 126 | + RQIterator end() { return RQIterator(n_rates_, n_rates_, pack_.my_rates()); } |
| 127 | +}; |
| 128 | + |
| 129 | +using ParametrizedRateQueryTest = grtest::ParametrizedConfigPresetFixture; |
| 130 | + |
| 131 | +TEST_P(ParametrizedRateQueryTest, AllUnique) { |
| 132 | + std::set<std::string> name_set; |
| 133 | + std::set<grunstable_rateid_type> id_set; |
| 134 | + for (const RateNameIdPair pair : RateQueryRange(pack)) { |
| 135 | + ASSERT_TRUE(name_set.insert(pair.name).second) |
| 136 | + << "the name, \"" << pair.name << "\" appears more than once"; |
| 137 | + ASSERT_TRUE(id_set.insert(pair.rateid).second) |
| 138 | + << "the id, " << pair.rateid << " appears more than once"; |
| 139 | + } |
| 140 | +} |
| 141 | + |
| 142 | +TEST_P(ParametrizedRateQueryTest, ConsistentIDs) { |
| 143 | + for (const RateNameIdPair pair : RateQueryRange(pack)) { |
| 144 | + grunstable_rateid_type rateid = grunstable_ratequery_id(pair.name.c_str()); |
| 145 | + EXPECT_EQ(rateid, pair.rateid); |
| 146 | + } |
| 147 | +} |
| 148 | + |
| 149 | +using grtest::ChemPreset; |
| 150 | +using grtest::FullConfPreset; |
| 151 | +using grtest::InitialUnitPreset; |
| 152 | + |
| 153 | +INSTANTIATE_TEST_SUITE_P( |
| 154 | + /* 1st arg is intentionally empty */, ParametrizedRateQueryTest, |
| 155 | + ::testing::Values( |
| 156 | + FullConfPreset{ChemPreset::primchem0, InitialUnitPreset::simple_z0}, |
| 157 | + FullConfPreset{ChemPreset::primchem1, InitialUnitPreset::simple_z0}, |
| 158 | + FullConfPreset{ChemPreset::primchem2, InitialUnitPreset::simple_z0}, |
| 159 | + FullConfPreset{ChemPreset::primchem3, InitialUnitPreset::simple_z0}, |
| 160 | + FullConfPreset{ChemPreset::primchem4_dustspecies3, |
| 161 | + InitialUnitPreset::simple_z0})); |
0 commit comments