Line data Source code
1 : // Copyright (c) 2015-2022 Made to Order Software Corp. All Rights Reserved 2 : // 3 : // https://snapwebsites.org/project/csspp 4 : // contact@m2osw.com 5 : // 6 : // This program is free software; you can redistribute it and/or modify 7 : // it under the terms of the GNU General Public License as published by 8 : // the Free Software Foundation; either version 2 of the License, or 9 : // (at your option) any later version. 10 : // 11 : // This program is distributed in the hope that it will be useful, 12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : // GNU General Public License for more details. 15 : // 16 : // You should have received a copy of the GNU General Public License along 17 : // with this program; if not, write to the Free Software Foundation, Inc., 18 : // 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 : 20 : /** \file 21 : * \brief Test the nth_child.cpp file. 22 : * 23 : * This test runs a battery of tests agains the nth_child.cpp 24 : * implementation to ensure full coverage. 25 : */ 26 : 27 : // csspp 28 : // 29 : #include "csspp/nth_child.h" 30 : 31 : 32 : // self 33 : // 34 : #include "catch_main.h" 35 : 36 : 37 : // C++ 38 : // 39 : #include <sstream> 40 : 41 : 42 : // last include 43 : // 44 : #include <snapdev/poison.h> 45 : 46 : 47 : 48 : 49 : namespace 50 : { 51 : 52 : 53 : } // no name namespace 54 : 55 : 56 1 : CATCH_TEST_CASE("Nth child", "[nth-child] [constructors]") 57 : { 58 : { 59 1 : csspp::nth_child a((4LL << 32) + 3); 60 1 : CATCH_REQUIRE(a.get_a() == 3); 61 1 : CATCH_REQUIRE(a.get_b() == 4); 62 1 : CATCH_REQUIRE(a.get_nth() == ((4LL << 32) + 3)); 63 1 : CATCH_REQUIRE(a.get_error() == ""); 64 1 : CATCH_REQUIRE(a.to_string() == "3n+4"); 65 1 : } 66 : 67 : { 68 1 : csspp::nth_child a(3, 4); 69 1 : CATCH_REQUIRE(a.get_a() == 3); 70 1 : CATCH_REQUIRE(a.get_b() == 4); 71 1 : CATCH_REQUIRE(a.get_nth() == ((4LL << 32) + 3)); 72 1 : CATCH_REQUIRE(a.get_error() == ""); 73 1 : CATCH_REQUIRE(a.to_string() == "3n+4"); 74 1 : } 75 : 76 : { 77 3 : csspp::nth_child a("3n+4"); 78 1 : CATCH_REQUIRE(a.get_a() == 3); 79 1 : CATCH_REQUIRE(a.get_b() == 4); 80 1 : CATCH_REQUIRE(a.get_nth() == ((4LL << 32) + 3)); 81 1 : CATCH_REQUIRE(a.get_error() == ""); 82 1 : CATCH_REQUIRE(a.to_string() == "3n+4"); 83 1 : } 84 : 85 : // no error left over 86 1 : VERIFY_ERRORS(""); 87 1 : } 88 : 89 1 : CATCH_TEST_CASE("Simple nth child", "[nth-child] [basics]") 90 : { 91 : { 92 1 : csspp::nth_child a(-3, 9); 93 1 : CATCH_REQUIRE(a.get_a() == -3); 94 1 : CATCH_REQUIRE(a.get_b() == 9); 95 1 : CATCH_REQUIRE(a.get_nth() == ((9LL << 32) + 0xFFFFFFFD)); 96 1 : CATCH_REQUIRE(a.get_error() == ""); 97 1 : CATCH_REQUIRE(a.to_string() == "-3n+9"); 98 : 99 : // special cases 100 1 : a.parse("odd"); 101 1 : CATCH_REQUIRE(a.get_a() == 2); 102 1 : CATCH_REQUIRE(a.get_b() == 1); 103 1 : CATCH_REQUIRE(a.get_nth() == ((1LL << 32) + 2)); 104 1 : CATCH_REQUIRE(a.get_error() == ""); 105 1 : CATCH_REQUIRE(a.to_string() == "odd"); 106 : 107 1 : a.parse("even"); 108 1 : CATCH_REQUIRE(a.get_a() == 2); 109 1 : CATCH_REQUIRE(a.get_b() == 0); 110 1 : CATCH_REQUIRE(a.get_nth() == ((0LL << 32) + 2)); 111 1 : CATCH_REQUIRE(a.get_error() == ""); 112 1 : CATCH_REQUIRE(a.to_string() == "2n"); 113 1 : } 114 : 115 : { 116 1 : csspp::nth_child a(3, 4); 117 1 : CATCH_REQUIRE(a.get_a() == 3); 118 1 : CATCH_REQUIRE(a.get_b() == 4); 119 1 : CATCH_REQUIRE(a.get_nth() == ((4LL << 32) + 3)); 120 1 : CATCH_REQUIRE(a.get_error() == ""); 121 1 : CATCH_REQUIRE(a.to_string() == "3n+4"); 122 : 123 1 : std::string expected; 124 202 : for(int i(-100); i <= 100; ++i) 125 : { 126 40602 : for(int j(-100); j <= 100; ++j) 127 : { 128 40401 : a.set_a(i); 129 40401 : a.set_b(j); 130 : 131 40401 : CATCH_REQUIRE(a.get_a() == i); 132 40401 : CATCH_REQUIRE(a.get_b() == j); 133 40401 : CATCH_REQUIRE(a.get_nth() == ((static_cast<csspp::integer_t>(j) << 32) + (i & 0xFFFFFFFF))); 134 40401 : CATCH_REQUIRE(a.get_error() == ""); 135 40401 : if(i == 2 && j == 1) 136 : { 137 1 : expected = "odd"; 138 : } 139 40400 : else if(i == 0) 140 : { 141 201 : expected = std::to_string(j); 142 : } 143 40199 : else if(j == 0) 144 : { 145 200 : expected = std::to_string(i) + "n"; 146 : } 147 : else 148 : { 149 39999 : expected = std::to_string(i) + "n" + (j >= 0 ? "+" : "") + std::to_string(j); 150 : } 151 40401 : CATCH_REQUIRE(a.to_string() == expected); 152 : 153 : // try all combos with spaces 154 2626065 : for(int k(0); k < (1 << 6); ++k) 155 : { 156 5171328 : a.parse( 157 5171328 : std::string((k & (1 << 0)) ? " " : "") 158 7756992 : + (i >= 0 ? (rand() % 5 == 0 ? "+" : "") : "-") 159 7756992 : + ((k & (1 << 1)) ? " " : "") 160 10342656 : + std::to_string(abs(i)) 161 7756992 : + ((k & (1 << 2)) ? " " : "") // this one should be illegal, we may enforce it later 162 7756992 : + "n" 163 7756992 : + ((k & (1 << 3)) ? " " : "") 164 7756992 : + (j >= 0 ? "+" : "-") 165 7756992 : + ((k & (1 << 4)) ? " " : "") 166 10342656 : + std::to_string(abs(j)) 167 7756992 : + ((k & (1 << 5)) ? " " : "") 168 : ); 169 : 170 2585664 : CATCH_REQUIRE(a.get_a() == i); 171 2585664 : CATCH_REQUIRE(a.get_b() == j); 172 2585664 : CATCH_REQUIRE(a.get_nth() == ((static_cast<csspp::integer_t>(j) << 32) + (i & 0xFFFFFFFF))); 173 2585664 : CATCH_REQUIRE(a.get_error() == ""); 174 2585664 : CATCH_REQUIRE(a.to_string() == expected); 175 : } 176 : 177 40401 : if(i == 0) 178 : { 179 1809 : for(int k(0); k < (1 << 3); ++k) 180 : { 181 3216 : a.parse( 182 3216 : std::string((k & (1 << 0)) ? " " : "") 183 4824 : + (j >= 0 ? (rand() % 5 <= 2 ? "+" : "") : "-") 184 4824 : + ((k & (1 << 1)) ? " " : "") 185 6432 : + std::to_string(abs(j)) 186 4824 : + ((k & (1 << 2)) ? " " : "") 187 : ); 188 : 189 1608 : CATCH_REQUIRE(a.get_a() == i); 190 1608 : CATCH_REQUIRE(a.get_b() == j); 191 1608 : CATCH_REQUIRE(a.get_nth() == ((static_cast<csspp::integer_t>(j) << 32) + (i & 0xFFFFFFFF))); 192 1608 : CATCH_REQUIRE(a.get_error() == ""); 193 1608 : CATCH_REQUIRE(a.to_string() == expected); 194 : } 195 : } 196 : } 197 : } 198 1 : } 199 : 200 : // no error left over 201 1 : VERIFY_ERRORS(""); 202 1 : } 203 : 204 1 : CATCH_TEST_CASE("Invalid nth child", "[nth-child] [invalid]") 205 : { 206 : { 207 1 : csspp::nth_child a(5, 3); 208 1 : CATCH_REQUIRE(a.get_a() == 5); 209 1 : CATCH_REQUIRE(a.get_b() == 3); 210 1 : CATCH_REQUIRE(a.get_nth() == ((3LL << 32) + 5)); 211 1 : CATCH_REQUIRE(a.get_error() == ""); 212 1 : CATCH_REQUIRE(a.to_string() == "5n+3"); 213 : 214 1 : CATCH_REQUIRE_FALSE(a.parse("random")); 215 1 : CATCH_REQUIRE(a.get_error() == "In an An+B expression, we expect an optional signed followed by a number or 'even' or 'odd'."); 216 : 217 1 : CATCH_REQUIRE_FALSE(a.parse("electric")); 218 1 : CATCH_REQUIRE(a.get_error() == "In an An+B expression, we expect an optional signed followed by a number or 'even' or 'odd'."); 219 : 220 1 : CATCH_REQUIRE_FALSE(a.parse("even3")); 221 1 : CATCH_REQUIRE(a.get_error() == "'even' cannot be followed by anything else in an An+B expression."); 222 : 223 1 : CATCH_REQUIRE_FALSE(a.parse("odor")); 224 1 : CATCH_REQUIRE(a.get_error() == "In an An+B expression, we expect an optional signed followed by a number or 'even' or 'odd'."); 225 : 226 1 : CATCH_REQUIRE_FALSE(a.parse("odd+3")); 227 1 : CATCH_REQUIRE(a.get_error() == "'odd' cannot be followed by anything else in an An+B expression."); 228 : 229 1 : CATCH_REQUIRE_FALSE(a.parse("++5")); 230 1 : CATCH_REQUIRE(a.get_error() == "In an An+B expression, we expect an optional signed followed by a number or 'even' or 'odd'."); 231 : 232 1 : CATCH_REQUIRE_FALSE(a.parse("--5")); 233 1 : CATCH_REQUIRE(a.get_error() == "In an An+B expression, we expect an optional signed followed by a number or 'even' or 'odd'."); 234 : 235 1 : CATCH_REQUIRE_FALSE(a.parse("5+3")); 236 1 : CATCH_REQUIRE(a.get_error() == "The first number has to be followed by the 'n' character."); 237 : 238 1 : CATCH_REQUIRE_FALSE(a.parse("5n3")); 239 1 : CATCH_REQUIRE(a.get_error() == "A sign (+ or -) is expected between the 'An' and the 'B' parts in 'An+B'."); 240 : 241 1 : CATCH_REQUIRE_FALSE(a.parse("5n+odd")); 242 1 : CATCH_REQUIRE(a.get_error() == "The value B must be a valid integer in 'An+B'."); 243 : 244 1 : CATCH_REQUIRE_FALSE(a.parse("5n+even")); 245 1 : CATCH_REQUIRE(a.get_error() == "The value B must be a valid integer in 'An+B'."); 246 : 247 1 : CATCH_REQUIRE_FALSE(a.parse("5n++")); 248 1 : CATCH_REQUIRE(a.get_error() == "The value B must be a valid integer in 'An+B'."); 249 : 250 1 : CATCH_REQUIRE_FALSE(a.parse("5n-+")); 251 1 : CATCH_REQUIRE(a.get_error() == "The value B must be a valid integer in 'An+B'."); 252 : 253 1 : CATCH_REQUIRE_FALSE(a.parse("5n+-")); 254 1 : CATCH_REQUIRE(a.get_error() == "The value B must be a valid integer in 'An+B'."); 255 : 256 1 : CATCH_REQUIRE_FALSE(a.parse("5n--")); 257 1 : CATCH_REQUIRE(a.get_error() == "The value B must be a valid integer in 'An+B'."); 258 : 259 1 : CATCH_REQUIRE_FALSE(a.parse("5n-3odd")); 260 1 : CATCH_REQUIRE(a.get_error() == "An 'An+B' expression cannot be followed by anything else."); 261 : 262 1 : CATCH_REQUIRE_FALSE(a.parse("5n-3even")); 263 1 : CATCH_REQUIRE(a.get_error() == "An 'An+B' expression cannot be followed by anything else."); 264 : 265 1 : CATCH_REQUIRE_FALSE(a.parse("5n-3+")); 266 1 : CATCH_REQUIRE(a.get_error() == "An 'An+B' expression cannot be followed by anything else."); 267 : 268 1 : CATCH_REQUIRE_FALSE(a.parse("5n-3-")); 269 1 : CATCH_REQUIRE(a.get_error() == "An 'An+B' expression cannot be followed by anything else."); 270 : 271 1 : CATCH_REQUIRE_FALSE(a.parse("5n-3 3")); 272 1 : CATCH_REQUIRE(a.get_error() == "An 'An+B' expression cannot be followed by anything else."); 273 : 274 1 : CATCH_REQUIRE_FALSE(a.parse("5n-3n")); 275 1 : CATCH_REQUIRE(a.get_error() == "An 'An+B' expression cannot be followed by anything else."); 276 1 : } 277 : 278 : // no error left over 279 1 : VERIFY_ERRORS(""); 280 1 : } 281 : 282 : // vim: ts=4 sw=4 et