1 2 module dquery.tests.regression; 3 4 import dquery.d; 5 6 version(unittest) 7 { 8 struct Coord 9 { 10 11 private 12 { 13 struct Attr 14 { 15 } 16 17 struct Limit 18 { 19 int value; 20 } 21 22 struct None 23 { 24 } 25 } 26 27 @Attr 28 @Limit(10) 29 int x; 30 31 @Attr 32 @Limit(10) 33 int y; 34 35 @Attr 36 @Limit(10) 37 int z; 38 39 int tmp; 40 41 @disable this(); 42 43 this(int x, int y, int z) 44 { 45 this.x = x; 46 this.y = y; 47 this.z = z; 48 } 49 50 void reset() 51 { 52 x = y = z = 0; 53 } 54 55 int[3] getCoords() 56 { 57 return [x, y, z]; 58 } 59 } 60 } 61 62 unittest 63 { 64 alias Attr = Coord.Attr; 65 alias Limit = Coord.Limit; 66 alias None = Coord.None; 67 68 Coord coord = Coord(1, 2, 3); 69 auto query = coord.query; 70 71 // Should not be empty. 72 static assert(!query.empty); 73 74 // Should have 11 elements. 75 static assert(query.length == 11); 76 77 auto fields = query.fields; 78 79 // Should match parent type. 80 static assert(is(fields.type == query.type)); 81 82 // Should not be empty. 83 static assert(!fields.empty); 84 85 // Should have 4 elements. 86 static assert(fields.length == 4); 87 88 foreach(element; fields) 89 { 90 // Should match parent type. 91 static assert(is(element.type == fields.type)); 92 93 static if(!element.isName!"tmp") 94 { 95 // Should have attribute Attr. 96 static assert(element.hasAttribute!Attr); 97 98 // Should have attribute Limit. 99 static assert(element.hasAttribute!Limit); 100 101 // Should not have attribute None. 102 static assert(!element.hasAttribute!None); 103 104 // Should not have nonexistent elements. 105 static assert(element.attributes.anyOf!None.empty); 106 107 // Should not have noneOfden elements. 108 static assert(element.attributes.noneOf!(Attr, Limit).empty); 109 110 foreach(attribute; element.attributes.anyOf!Attr) 111 { 112 // Should be a type attribute. 113 static assert(attribute.isType); 114 115 // Should not be an expression attribute. 116 static assert(!attribute.isExpression); 117 118 // Should be type Attr. 119 static assert(attribute.isTypeOf!Attr); 120 121 // Should not be type None. 122 static assert(!attribute.isTypeOf!None); 123 124 // Should be assignable to Attr. 125 static assert(attribute.isTypeAssignableTo!Attr); 126 127 // Should not be assignable to None. 128 static assert(!attribute.isTypeAssignableTo!None); 129 130 // Should be assignable from Attr. 131 static assert(attribute.isTypeAssignableFrom!Attr); 132 133 // Should not be assignable from None. 134 static assert(!attribute.isTypeAssignableFrom!None); 135 } 136 137 foreach(attribute; element.attributes.anyOf!Limit) 138 { 139 // Should be a type attribute. 140 static assert(!attribute.isType); 141 142 // Should not be an expression attribute. 143 static assert(attribute.isExpression); 144 145 // Should be type Limit. 146 static assert(attribute.isTypeOf!Limit); 147 148 // Should not be type None. 149 static assert(!attribute.isTypeOf!None); 150 151 // Should be assignable to Limit. 152 static assert(attribute.isTypeAssignableTo!Limit); 153 154 // Should not be assignable to None. 155 static assert(!attribute.isTypeAssignableTo!None); 156 157 // Should be assignable from Limit. 158 static assert(attribute.isTypeAssignableFrom!Limit); 159 160 // Should not be assignable from None. 161 static assert(!attribute.isTypeAssignableFrom!None); 162 } 163 } 164 else 165 { 166 // Should not have attribute Attr. 167 static assert(!element.hasAttribute!Attr); 168 169 // Should not have attribute Limit. 170 static assert(!element.hasAttribute!Limit); 171 172 // Should not have attribute None. 173 static assert(!element.hasAttribute!None); 174 175 // Should not have nonexistent elements. 176 static assert(element.attributes.anyOf!None.empty); 177 178 // Should not have anyOfed but nonexistent elements. 179 static assert(element.attributes.anyOf!(Attr, Limit).empty); 180 181 // Should not have noneOfden elements. 182 static assert(element.attributes.noneOf!(Attr, Limit).empty); 183 } 184 185 // Should have public protection. 186 static assert(element.protection == "public"); 187 188 // Should be a field. 189 static assert(element.isField); 190 191 // Should be an int. 192 static assert(element.isTypeOf!int); 193 194 // Should be not a ulong. 195 static assert(!element.isTypeOf!ulong); 196 197 // Should be assignable to int. 198 static assert(element.isTypeAssignableTo!int); 199 200 // Should be assignable to ulong. 201 static assert(element.isTypeAssignableTo!ulong); 202 203 // Should be assignable from int. 204 static assert(element.isTypeAssignableFrom!int); 205 206 // Should not be assignable from ulong. 207 static assert(!element.isTypeAssignableFrom!ulong); 208 209 // Should not be a function. 210 static assert(!element.isFunction); 211 212 // Should not have arity 0. 213 static assert(!element.isArity!0); 214 215 // Should not return an int. 216 static assert(!element.isReturnTypeOf!int); 217 218 // Should not be an aggregate. 219 static assert(!element.isAggregate); 220 221 // Should not be a class. 222 static assert(!element.isClass); 223 224 // Should not be a struct. 225 static assert(!element.isStruct); 226 } 227 228 auto namedFields = fields.names!("x", "z"); 229 230 // Should match parent type. 231 static assert(is(namedFields.type == fields.type)); 232 233 // Should not be empty. 234 static assert(!namedFields.empty); 235 236 // Should have 2 elements. 237 static assert(namedFields.length == 2); 238 239 foreach(element; namedFields) 240 { 241 // Should match parent type. 242 static assert(is(element.type == namedFields.type)); 243 244 // Should not be field y. 245 static assert(!element.isName!"y"); 246 247 // Should be one of fields x or z. 248 static assert( 249 element.isName!"x" || 250 element.isName!"z" 251 ); 252 } 253 254 auto anyOfedFields = fields.anyOf!Attr; 255 256 // Should match parent type. 257 static assert(is(anyOfedFields.type == fields.type)); 258 259 // Should not be empty. 260 static assert(!anyOfedFields.empty); 261 262 // Should have 3 elements. 263 static assert(anyOfedFields.length == 3); 264 265 foreach(element; anyOfedFields) 266 { 267 // Should match parent type. 268 static assert(is(element.type == anyOfedFields.type)); 269 270 // Should not be field tmp. 271 static assert(!element.isName!"tmp"); 272 273 // Should have attribute Attr. 274 static assert(element.hasAttribute!Attr); 275 } 276 277 auto noneOfdenFields = fields.noneOf!Limit; 278 279 // Should match parent type. 280 static assert(is(noneOfdenFields.type == fields.type)); 281 282 // Should not be empty. 283 static assert(!noneOfdenFields.empty); 284 285 // Should have 1 element. 286 static assert(noneOfdenFields.length == 1); 287 288 foreach(element; noneOfdenFields) 289 { 290 // Should match parent type. 291 static assert(is(element.type == noneOfdenFields.type)); 292 293 // Should be field tmp. 294 static assert(element.isName!"tmp"); 295 296 // Should have attribute Other. 297 static assert(!element.hasAttribute!Limit); 298 299 // Should have no attributes. 300 static assert(element.attributes.empty); 301 } 302 303 auto functions = query.functions; 304 305 // Should not be empty. 306 static assert(!functions.empty); 307 308 // Should have 4 elements. 309 static assert(functions.length == 4); 310 311 foreach(element; functions) 312 { 313 // Should match parent type. 314 static assert(is(element.type == fields.type)); 315 316 // Should not have attribute Attr. 317 static assert(!element.hasAttribute!Attr); 318 319 // Should not have attribute Limit. 320 static assert(!element.hasAttribute!Limit); 321 322 // Should not have attribute None. 323 static assert(!element.hasAttribute!None); 324 325 // Should not have nonexistent elements. 326 static assert(element.attributes.anyOf!None.empty); 327 328 // Should not have noneOfden elements. 329 static assert(element.attributes.noneOf!(Attr, Limit).empty); 330 331 // Should have public protection. 332 static assert(element.protection == "public"); 333 334 // Should not be a field. 335 static assert(!element.isField); 336 337 // Should be an int. 338 static assert(!element.isTypeOf!int); 339 340 // Should be not a ulong. 341 static assert(!element.isTypeOf!ulong); 342 343 // Should be assignable to int. 344 static assert(!element.isTypeAssignableTo!int); 345 346 // Should be assignable to ulong. 347 static assert(!element.isTypeAssignableTo!ulong); 348 349 // Should be assignable from int. 350 static assert(!element.isTypeAssignableFrom!int); 351 352 // Should not be assignable from ulong. 353 static assert(!element.isTypeAssignableFrom!ulong); 354 355 // Should be a function. 356 static assert(element.isFunction); 357 358 static if(element.isName!"__ctor") 359 { 360 static if(element.isArity!0) 361 { 362 // Should have parameters (). 363 static assert(element.isParameterTypesOf!()); 364 365 // Should not have parameters (int). 366 static assert(!element.isParameterTypesOf!(int)); 367 368 // Should not have parameters (int, int, int). 369 static assert(!element.isParameterTypesOf!(int, int, int)); 370 371 // Should not return an int. 372 static assert(!element.isReturnTypeOf!int); 373 374 // Should return a Coord. 375 static assert(element.isReturnTypeOf!Coord); 376 } 377 else static if(element.isArity!3) 378 { 379 // Should not have parameters (). 380 static assert(!element.isParameterTypesOf!()); 381 382 // Should not have parameters (int). 383 static assert(!element.isParameterTypesOf!(int)); 384 385 // Should have parameters (int, int, int). 386 static assert(element.isParameterTypesOf!(int, int, int)); 387 388 // Should not return an int. 389 static assert(!element.isReturnTypeOf!int); 390 391 // Should return a Coord. 392 static assert(element.isReturnTypeOf!Coord); 393 } 394 else 395 { 396 static assert(0); 397 } 398 } 399 else static if(element.isName!"reset") 400 { 401 // Should have arity 0. 402 static assert(element.isArity!0); 403 404 // Should not have arity 3. 405 static assert(!element.isArity!3); 406 407 // Should have parameters (). 408 static assert(element.isParameterTypesOf!()); 409 410 // Should not have parameters (int). 411 static assert(!element.isParameterTypesOf!(int)); 412 413 // Should not have parameters (int, int, int). 414 static assert(!element.isParameterTypesOf!(int, int, int)); 415 416 // Should not return an int. 417 static assert(!element.isReturnTypeOf!int); 418 419 // Should not return an int array. 420 static assert(!element.isReturnTypeOf!(int[3])); 421 422 // Should return void. 423 static assert(element.isReturnTypeOf!void); 424 } 425 else static if(element.isName!"getCoords") 426 { 427 // Should have arity 0. 428 static assert(element.isArity!0); 429 430 // Should not have arity 3. 431 static assert(!element.isArity!3); 432 433 // Should have parameters (). 434 static assert(element.isParameterTypesOf!()); 435 436 // Should not have parameters (int). 437 static assert(!element.isParameterTypesOf!(int)); 438 439 // Should not have parameters (int, int, int). 440 static assert(!element.isParameterTypesOf!(int, int, int)); 441 442 // Should not return an int. 443 static assert(!element.isReturnTypeOf!int); 444 445 // Should return an int array. 446 static assert(element.isReturnTypeOf!(int[3])); 447 } 448 else 449 { 450 // Should not have any other elements. 451 static assert(0, "Unexpected element " ~ element.name); 452 } 453 454 // Should not be an aggregate. 455 static assert(!element.isAggregate); 456 457 // Should not be a class. 458 static assert(!element.isClass); 459 460 // Should not be a struct. 461 static assert(!element.isStruct); 462 } 463 464 auto aggregates = query.aggregates; 465 466 // Should not be empty. 467 static assert(!aggregates.empty); 468 469 // Should have 3 elements. 470 static assert(aggregates.length == 3); 471 472 foreach(element; aggregates) 473 { 474 // Should match parent type. 475 static assert(is(element.type == aggregates.type)); 476 477 // Should not have attribute Attr. 478 static assert(!element.hasAttribute!Attr); 479 480 // Should not have attribute Limit. 481 static assert(!element.hasAttribute!Limit); 482 483 // Should not have attribute None. 484 static assert(!element.hasAttribute!None); 485 486 // Should not have nonexistent elements. 487 static assert(element.attributes.anyOf!None.empty); 488 489 // Should not have noneOfden elements. 490 static assert(element.attributes.noneOf!(Attr, Limit).empty); 491 492 // Should have private protection. 493 static assert(element.protection == "private"); 494 495 // Should not be a field. 496 static assert(!element.isField); 497 498 // Should be an int. 499 static assert(!element.isTypeOf!int); 500 501 // Should be not a ulong. 502 static assert(!element.isTypeOf!ulong); 503 504 // Should be assignable to int. 505 static assert(!element.isTypeAssignableTo!int); 506 507 // Should be assignable to ulong. 508 static assert(!element.isTypeAssignableTo!ulong); 509 510 // Should be assignable from int. 511 static assert(!element.isTypeAssignableFrom!int); 512 513 // Should not be assignable from ulong. 514 static assert(!element.isTypeAssignableFrom!ulong); 515 516 // Should not be a function. 517 static assert(!element.isFunction); 518 519 // Should not have arity 0. 520 static assert(!element.isArity!0); 521 522 // Should not return an int. 523 static assert(!element.isReturnTypeOf!int); 524 525 // Should not return void. 526 static assert(!element.isReturnTypeOf!void); 527 528 // Should be an aggregate. 529 static assert(element.isAggregate); 530 531 // Should not be a class. 532 static assert(!element.isClass); 533 534 // Should be a struct. 535 static assert(element.isStruct); 536 537 auto subQuery = element.query; 538 539 // Should not match parent type. 540 static assert(!is(subQuery.type == element.type)); 541 542 static if(is(subQuery.type == Limit)) 543 { 544 // Should not be empty. 545 static assert(!subQuery.empty); 546 547 // Should have 1 element. 548 static assert(subQuery.length == 1); 549 } 550 else 551 { 552 // Should be empty. 553 static assert(subQuery.empty); 554 } 555 } 556 }