1 /**xpand 2 Tests "inspired" by the ones in dstep's UnitTests.d module 3 */ 4 module it.c.dstep.ut; 5 6 import it; 7 8 9 @("2 functions and a global variable") 10 @safe unittest { 11 shouldCompile( 12 C(q{ 13 float foo(int x); 14 float bar(int x); 15 int a; 16 } 17 ), 18 D( 19 20 q{ 21 float f = foo(42); 22 float b = bar(77); 23 a = 33; 24 } 25 ), 26 ); 27 28 } 29 30 @("extern int declared several times") 31 @safe unittest { 32 shouldCompile( 33 C( 34 q{ 35 extern int foo; 36 extern int bar; 37 extern int foo; 38 extern int foo; 39 } 40 ), 41 D( 42 43 q{ 44 foo = 5; 45 bar = 3; 46 } 47 ), 48 ); 49 } 50 51 @("array with #defined length") 52 @safe unittest { 53 shouldCompile( 54 C( 55 ` 56 #define FOO 4 57 char var[FOO]; 58 ` 59 ), 60 D( 61 q{ 62 static assert(var.sizeof == 4); 63 var[0] = cast(byte)3; 64 } 65 ), 66 ); 67 } 68 69 @("struct with array with #defined length") 70 @safe unittest { 71 shouldCompile( 72 C( 73 ` 74 #define BAR 128 75 76 struct Foo { 77 char var[BAR]; 78 }; 79 ` 80 ), 81 D( 82 q{ 83 auto f = Foo(); 84 static assert(f.var.sizeof == 128); 85 f.var[127] = cast(byte)3; 86 } 87 ), 88 ); 89 } 90 91 92 @("struct with 3d arrays of #defined length") 93 @safe unittest { 94 shouldCompile( 95 C( 96 ` 97 #define FOO 2 98 #define BAR 4 99 #define BAZ 8 100 101 struct Foo { 102 char var[FOO][BAR][BAZ]; 103 }; 104 ` 105 ), 106 D( 107 q{ 108 auto f = Foo(); 109 // opposite order than in C 110 static assert(f.var.length == 2); 111 static assert(f.var[0].length == 4); 112 static assert(f.var[0][0].length == 8); 113 auto v = f.var[0][0][7]; 114 } 115 ), 116 ); 117 } 118 119 @("nested anonymous structures") 120 @safe unittest { 121 shouldCompile( 122 C( 123 q{ 124 struct C { 125 struct { 126 int x; 127 int y; 128 129 struct { 130 int z; 131 int w; 132 } nested; 133 } point; 134 }; 135 } 136 ), 137 D( 138 139 q{ 140 auto c = C(); 141 c.point.x = 42; 142 c.point.y = 77; 143 c.point.nested.z = 2; 144 c.point.nested.w = 3; 145 } 146 ), 147 ); 148 149 } 150 151 @("interleaved enum-based array size consts and macro based array size counts") 152 @safe unittest { 153 shouldCompile( 154 C( 155 ` 156 struct qux { 157 char scale; 158 }; 159 160 #define FOO 2 161 #define BAZ 8 162 163 struct stats_t { 164 enum 165 { 166 BAR = 4, 167 }; 168 169 struct qux stat[FOO][BAR][FOO][BAZ]; 170 }; 171 ` 172 ), 173 D( 174 q{ 175 auto s = stats_t(); 176 // opposite order than in C 177 static assert(stats_t.BAR == 4); 178 // accessing at the limits of each dimension 179 auto q = s.stat[1][3][1][7]; 180 } 181 ), 182 ); 183 } 184 185 @("function pointer with unnamed parameter") 186 @safe unittest { 187 shouldCompile( 188 C( 189 q{ 190 typedef int (*read_char)(void *); 191 } 192 ), 193 D( 194 195 q{ 196 read_char func; 197 int val; 198 int ret = func(&val); 199 } 200 ), 201 ); 202 203 } 204 205 @("array typedef") 206 @safe unittest { 207 shouldCompile( 208 C( 209 q{ 210 typedef double foo[2]; 211 } 212 ), 213 D( 214 215 q{ 216 foo doubles; 217 static assert(doubles.length == 2); 218 doubles[0] = 33.3; 219 doubles[1] = 77.7; 220 } 221 ), 222 ); 223 224 } 225 226 @("array of structs declared immediately") 227 @safe unittest { 228 shouldCompile( 229 C( 230 q{ 231 struct Foo { 232 struct Bar { 233 } bar[64]; 234 }; 235 } 236 ), 237 D( 238 239 q{ 240 auto f = Foo(); 241 static assert(f.bar.length == 64); 242 f.bar[63] = Foo.Bar(); 243 } 244 ), 245 ); 246 247 } 248 249 @("variadic function without ...") 250 @safe unittest { 251 252 shouldCompile( 253 C( 254 q{ 255 // Since fully variadic C functions aren't allowed in D, 256 // we assume the header means `void foo(void);` 257 // The reason being that void foo(...) wouldn't compile 258 // anyway and it's possible they meant foo(void). 259 void foo(); 260 } 261 ), 262 D( 263 q{ 264 foo(); 265 static assert(!__traits(compiles, foo(2, 3))); 266 } 267 ), 268 ); 269 } 270 271 272 @("function pointers") 273 @safe unittest { 274 shouldCompile( 275 C( 276 q{ 277 typedef void* ClientData; 278 typedef struct { int dummy; } EntityInfo; 279 void (*fun)(ClientData client_data, const EntityInfo*, unsigned last); 280 } 281 ), 282 D( 283 284 q{ 285 auto eInfo = EntityInfo(77); 286 struct Data { int value; } 287 auto data = Data(42); 288 uint last = 33; 289 fun(&data, &eInfo, last); 290 } 291 ), 292 ); 293 294 } 295 296 297 @("array function parameters") 298 @safe unittest { 299 shouldCompile( 300 C( 301 q{ 302 int foo (int data[]); // int* 303 int bar (const int data[]); // const int* 304 int baz (const int data[32]); // const int* 305 int qux (const int data[32][64]); // const int(*)[64] 306 } 307 ), 308 D( 309 310 q{ 311 int* data; 312 foo(data); 313 bar(data); 314 baz(data); 315 316 const(int)* cdata; 317 static assert(!__traits(compiles, foo(cdata))); 318 bar(cdata); 319 baz(cdata); 320 321 static assert(!__traits(compiles, qux(data))); 322 static assert(!__traits(compiles, qux(cdata))); 323 const(int)[64] arr; 324 qux(&arr); 325 } 326 ), 327 ); 328 329 } 330 331 @("name collision between struct and function") 332 @safe unittest { 333 shouldCompile( 334 C( 335 q{ 336 struct foo; 337 struct foo { int i; }; 338 void foo(void); 339 } 340 ), 341 D( 342 343 q{ 344 foo f; 345 f.i = 42; 346 foo_(); 347 } 348 ), 349 ); 350 351 } 352 353 @("name collision between struct and enum") 354 @safe unittest { 355 shouldCompile( 356 C( 357 q{ 358 enum foo { FOO }; 359 void foo(void); 360 } 361 ), 362 D( 363 364 q{ 365 foo_(); 366 auto f1 = FOO; 367 foo f2 = foo.FOO; 368 } 369 ), 370 ); 371 372 } 373 374 @("function parameter of elaborate type") 375 @safe unittest { 376 shouldCompile( 377 C( 378 q{ 379 struct foo_t { int i; }; 380 void bar(const struct foo_t *foo); 381 } 382 ), 383 D( 384 385 q{ 386 auto f = foo_t(42); 387 bar(&f); 388 const cf = const foo_t(33); 389 bar(&cf); 390 } 391 ), 392 ); 393 394 } 395 396 @("packed struct") 397 @safe unittest { 398 shouldCompile( 399 C( 400 q{ 401 struct Foo { 402 char x; 403 short y; 404 int z; 405 } __attribute__((__packed__)); 406 } 407 ), 408 D( 409 q{ 410 static assert(Foo.sizeof == 7, "Foo should be 7 bytes"); 411 } 412 ), 413 ); 414 }