cursor_spec.rb (23795B)
1 # Copyright, 2010-2012 by Jari Bakken. 2 # Copyright, 2013, by Samuel G. D. Williams. <http://www.codeotaku.com> 3 # Copyright, 2013, by Garry C. Marshall. <http://www.meaningfulname.net> 4 # Copyright, 2014, by Masahiro Sano. 5 # 6 # Permission is hereby granted, free of charge, to any person obtaining a copy 7 # of this software and associated documentation files (the "Software"), to deal 8 # in the Software without restriction, including without limitation the rights 9 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 # copies of the Software, and to permit persons to whom the Software is 11 # furnished to do so, subject to the following conditions: 12 # 13 # The above copyright notice and this permission notice shall be included in 14 # all copies or substantial portions of the Software. 15 # 16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 # THE SOFTWARE. 23 24 describe "Function Call Cursors" do 25 let(:translation_unit) {Index.new.parse_translation_unit(fixture_path("class.cpp"))} 26 let(:cursor) {translation_unit.cursor} 27 let(:call) {find_first(cursor, :cursor_call_expr)} 28 29 it "should parse correctly" do 30 expect(translation_unit.diagnostics).to be_empty 31 end 32 33 it "should find a method call" do 34 expect(call).to_not be_nil 35 end 36 end 37 38 39 describe Cursor do 40 let(:cursor) { Index.new.parse_translation_unit(fixture_path("list.c")).cursor } 41 let(:cursor_cxx) { Index.new.parse_translation_unit(fixture_path("test.cxx")).cursor } 42 let(:cursor_canon) { Index.new.parse_translation_unit(fixture_path("canonical.c")).cursor } 43 let(:cursor_pp) { Index.new.parse_translation_unit(fixture_path("docs.c"),[],[],{detailed_preprocessing_record: true}).cursor } 44 45 it "can be obtained from a translation unit" do 46 expect(cursor).to be_kind_of(Cursor) 47 expect(cursor.kind).to equal(:cursor_translation_unit) 48 expect(cursor.null?).to equal(false) 49 expect(cursor.translation_unit?).to equal(true) 50 end 51 52 it "returns the source location of the cursor" do 53 location = cursor.location 54 expect(location).to be_kind_of(SourceLocation) 55 end 56 57 describe '#extent' do 58 let(:extent) { cursor.extent } 59 it "has an extent which is a SourceRange" do 60 expect(extent).to be_kind_of(SourceRange) 61 end 62 63 it 'has filename and posion at start point' do 64 expect(extent.start.file).to eq(fixture_path("list.c")) 65 expect(extent.start.line).to equal(1) 66 end 67 68 it 'has filename and posion at end point' do 69 expect(extent.end.file).to eq(fixture_path("list.c")) 70 expect(extent.end.line).to equal(12) 71 end 72 end 73 74 it "returns the path of the translation unit for the translation unit cursor" do 75 expect(cursor.display_name).to eq(fixture_path("list.c")) 76 expect(cursor.spelling).to eq(fixture_path("list.c")) 77 end 78 79 it "allows us to visit its children" do 80 counter = 0 81 cursor.visit_children do |cursor, parent| 82 counter += 1 83 :recurse 84 end 85 expect(counter).not_to equal(0) 86 end 87 88 describe "Null Cursor" do 89 it "can be a null cursor" do 90 expect(Cursor.null_cursor).to be_kind_of(Cursor) 91 expect(Cursor.null_cursor.kind).to equal(:cursor_invalid_file) 92 end 93 94 it "is null?" do 95 expect(Cursor.null_cursor.null?).to equal(true) 96 end 97 98 it "is invalid?" do 99 expect(Cursor.null_cursor.invalid?).to equal(true) 100 end 101 102 it "compares as equal to another null cursor instance" do 103 expect(Cursor.null_cursor).to eq(Cursor.null_cursor) 104 end 105 106 it "should not equal a Translation Unit cursor" do 107 expect(Cursor.null_cursor).not_to eq(cursor) 108 end 109 end 110 111 describe "Function Cursors" do 112 let (:func) { find_first(cursor, :cursor_function) } 113 114 it "is not invalid?" do 115 expect(func.invalid?).to equal(false) 116 end 117 118 it "can find the first function declaration" do 119 expect(func).not_to equal(nil) 120 expect(func.kind).to equal(:cursor_function) 121 end 122 123 it "has an extent representing the bounds of the function" do 124 expect(func.extent).to be_kind_of(SourceRange) 125 expect(func.extent.start.line).to equal(5) 126 expect(func.extent.end.line).to equal(5) 127 end 128 129 it "returns the name of the function" do 130 expect(func.spelling).to eq("sum") 131 expect(func.display_name).to eq("sum(union List *)") 132 end 133 end 134 135 describe "Struct Cursors" do 136 let (:struct) { find_first(cursor, :cursor_struct) } 137 138 it "can find the first struct" do 139 expect(struct).not_to equal(nil) 140 expect(struct.kind).to equal(:cursor_struct) 141 end 142 143 it "has an extent representing the bounds of the struct" do 144 expect(struct.extent.start.line).to equal(1) 145 expect(struct.extent.end.line).to equal(4) 146 end 147 148 it "returns the name of the struct" do 149 expect(struct.spelling).to eq("List") 150 expect(struct.display_name).to eq("List") 151 end 152 153 end 154 155 describe '#kind_spelling' do 156 let (:struct) { find_first(cursor, :cursor_struct) } 157 158 it "returns the spelling of the given kind" do 159 expect(struct.kind_spelling).to eq('StructDecl') 160 end 161 end 162 163 describe '#declaration?' do 164 let (:struct) { find_first(cursor, :cursor_struct) } 165 166 it "checks the cursor is declaration" do 167 expect(struct.declaration?).to be true 168 end 169 end 170 171 describe '#reference?' do 172 let (:ref) { find_first(cursor, :cursor_type_ref) } 173 174 it "checks the cursor is reference" do 175 expect(ref.reference?).to be true 176 end 177 end 178 179 describe '#expression?' do 180 let (:literal) { find_first(cursor, :cursor_integer_literal) } 181 182 it "checks the cursor is expression" do 183 expect(literal.expression?).to be true 184 end 185 end 186 187 describe '#statement?' do 188 let (:return_stmt) { find_first(cursor, :cursor_return_stmt) } 189 190 it "checks the cursor is statement" do 191 expect(return_stmt.statement?).to be true 192 end 193 end 194 195 describe '#attribute?' do 196 let (:attr) { find_first(cursor_cxx, :cursor_unexposed_attr) } 197 198 it "checks the cursor is attribute" do 199 expect(attr.attribute?).to be true 200 end 201 end 202 203 describe '#public?' do 204 let(:public_cursor) { find_matching(cursor_cxx) { |child, parent| 205 child.kind == :cursor_field_decl and child.spelling == 'public_member_int' } } 206 207 it 'checks access control level is public' do 208 expect(public_cursor.public?).to be true 209 end 210 end 211 212 describe '#private?' do 213 let(:private_cursor) { find_matching(cursor_cxx) { |child, parent| 214 child.kind == :cursor_field_decl and child.spelling == 'private_member_int' } } 215 216 it 'checks access control level is private' do 217 expect(private_cursor.private?).to be true 218 end 219 end 220 221 describe '#protected?' do 222 let(:protected_cursor) { find_matching(cursor_cxx) { |child, parent| 223 child.kind == :cursor_field_decl and child.spelling == 'protected_member_int' } } 224 225 it 'checks access control level is protected' do 226 expect(protected_cursor.protected?).to be true 227 end 228 end 229 230 describe '#preprocessing?' do 231 let (:pp) { find_first(cursor_pp, :cursor_macro_definition) } 232 233 it 'checks the cursor is preprocessing' do 234 expect(pp.preprocessing?).to be true 235 end 236 end 237 238 describe '#unexposed?' do 239 let(:unexposed_cursor) { find_matching(cursor_cxx) { |child, parent| 240 child.kind == :cursor_unexposed_expr and child.spelling == 'func_overloaded' } } 241 242 it 'checks the cursor is unexposed' do 243 expect(unexposed_cursor.unexposed?).to be true 244 end 245 end 246 247 describe '#virtual_base?' do 248 let(:virtual_base_cursor) { find_matching(cursor_cxx) { |child, parent| 249 child.kind == :cursor_cxx_base_specifier and parent.spelling == 'B' } } 250 251 it 'checks cursor is virtual base' do 252 expect(virtual_base_cursor.virtual_base?).to equal true 253 end 254 end 255 256 describe '#virtual?' do 257 let(:virtual_cursor) { find_matching(cursor_cxx) { |child, parent| 258 child.kind == :cursor_cxx_method and child.spelling == 'func_a' } } 259 260 it 'checks member function is virtual' do 261 expect(virtual_cursor.virtual?).to equal true 262 end 263 end 264 265 describe '#pure_virtual?' do 266 let(:pure_virtual_cursor) { find_matching(cursor_cxx) { |child, parent| 267 child.kind == :cursor_cxx_method and 268 child.spelling == 'func_a' and parent.spelling == 'A' } } 269 270 it 'checks member function is purely virtual' do 271 expect(pure_virtual_cursor.pure_virtual?).to equal true 272 end 273 end 274 275 describe '#static?' do 276 let(:static_method_cursor) { find_matching(cursor_cxx) { |child, parent| 277 child.kind == :cursor_cxx_method and child.spelling == 'func_b' } } 278 279 it 'checks cursor is static member function' do 280 expect(static_method_cursor.static?).to equal true 281 end 282 end 283 284 describe '#enum_value' do 285 let(:enum_value_cursor) { find_matching(cursor_cxx) { |child, parent| 286 child.kind == :cursor_enum_constant_decl and child.spelling == 'EnumC' } } 287 288 it 'returns enum value' do 289 expect(enum_value_cursor.enum_value).to equal 100 290 end 291 end 292 293 describe '#enum_unsigned_value' do 294 let(:enum_value_cursor) { find_matching(cursor_cxx) { |child, parent| 295 child.kind == :cursor_enum_constant_decl and child.spelling == 'EnumC' } } 296 297 it 'returns enum unsigned value' do 298 expect(enum_value_cursor.enum_unsigned_value).to eq(100) 299 end 300 end 301 302 describe '#dynamic_call?' do 303 let(:dynamic_call) { find_matching(cursor_cxx) { |child, parent| 304 child.kind == :cursor_call_expr and child.spelling == 'func_a' and 305 child.semantic_parent.spelling == 'f_dynamic_call' } } 306 307 it 'checks if the method call is dynamic' do 308 expect(dynamic_call.dynamic_call?).to be true 309 end 310 end 311 312 describe '#specialized_template' do # looks not working on 3.2 313 let(:cursor_function) { find_matching(cursor_cxx) { |child, parent| 314 child.kind == :cursor_function and child.spelling == 'func_overloaded' } } 315 316 it "returns a cursor that may represent a specialization or instantiation of a template" do 317 expect(cursor_function.specialized_template).to be_kind_of(Cursor) 318 expect(cursor_function.specialized_template.kind).to be(:cursor_function_template) 319 end 320 end 321 322 describe '#canonical' do 323 let (:structs) { find_all(cursor_canon, :cursor_struct) } 324 325 it "mathes 3 cursors" do 326 expect(structs.size).to eq(3) 327 end 328 329 it "refers the first cursor as canonical one" do 330 expect(structs[0].canonical).to eq(structs[0]) 331 expect(structs[1].canonical).to eq(structs[0]) 332 expect(structs[2].canonical).to eq(structs[0]) 333 end 334 end 335 336 describe '#definition' do 337 let (:structs) { find_all(cursor_canon, :cursor_struct) } 338 339 it "mathes 3 cursors" do 340 expect(structs.size).to eq(3) 341 end 342 343 it "refers the third cursor as definition one" do 344 expect(structs[0].definition).to eq(structs[2]) 345 expect(structs[1].definition).to eq(structs[2]) 346 expect(structs[2].definition).to eq(structs[2]) 347 end 348 end 349 350 describe '#template_kind' do # looks not working on 3.2 351 let(:template) { find_matching(cursor_cxx) { |child, parent| 352 child.kind == :cursor_function_template and child.spelling == 'func_overloaded' } } 353 354 it "returns the cursor kind of the specializations would be generated" do 355 expect(template.template_kind).to be_kind_of(Symbol) 356 expect(template.template_kind).to be(:cursor_function) 357 end 358 end 359 360 describe '#access_specifier' do 361 let(:access_specifier_cursor) { find_matching(cursor_cxx) { |child, parent| 362 child.kind == :cursor_cxx_method and child.spelling == 'func_d' } } 363 364 it 'returns access specifier symbol' do 365 expect(access_specifier_cursor.access_specifier).to equal :private 366 end 367 end 368 369 describe '#language' do 370 let(:c_language_cursor) { find_matching(cursor) { |c, p| c.kind == :cursor_struct } } 371 let(:cxx_language_cursor) { find_matching(cursor_cxx) { |c, p| c.kind == :cursor_struct } } 372 373 it 'returns :c if the cursor language is C' do 374 expect(c_language_cursor.language).to equal :c 375 end 376 377 it 'returns :c_plus_plus if the cursor language is C++' do 378 expect(cxx_language_cursor.language).to equal :c_plus_plus 379 end 380 end 381 382 describe '#translation_unit' do 383 let (:struct) { find_first(cursor, :cursor_struct) } 384 385 it "can find the first struct" do 386 expect(struct).not_to equal(nil) 387 end 388 389 it "returns the translation unit that a cursor originated from" do 390 expect(struct.translation_unit).to be_kind_of(TranslationUnit) 391 expect(struct.translation_unit.spelling).to eq(fixture_path("list.c")) 392 end 393 end 394 395 describe '#find_references_in_file' do 396 let (:struct_cursor) {find_first(cursor_canon, :cursor_struct) } 397 398 it "visits references to the cursor in the main file" do 399 counter = 0 400 struct_cursor.find_references_in_file do |ref_cursor, ref_src_loc| 401 counter += 1 402 :continue 403 end 404 expect(counter).not_to equal(0) 405 end 406 407 it "visits references to the cursor in the indicated file" do 408 counter = 0 409 struct_cursor.find_references_in_file(fixture_path("canonical.c")) do |ref_cursor, ref_src_loc| 410 counter += 1 411 :continue 412 end 413 expect(counter).not_to equal(0) 414 end 415 end 416 417 describe '#linkage' do 418 let (:ref) { find_first(cursor, :cursor_type_ref) } 419 let (:func) { find_first(cursor, :cursor_function) } 420 421 it "returns :external if the cursor is non-static function" do 422 expect(func.linkage).to equal :external 423 end 424 425 it "returns :invalid if the cursor does not have linkage" do 426 expect(ref.linkage).to equal :invalid 427 end 428 end 429 430 describe '#semantic_parent' do 431 let(:parent) { find_matching(cursor_cxx) { |child, parent| 432 child.kind == :cursor_cxx_method and child.spelling == 'func_d' and parent.spelling != 'D' } } 433 434 it 'returns base class as semantic parent' do 435 expect(parent.semantic_parent.spelling).to eq('D') 436 end 437 end 438 439 describe '#lexical_parent' do 440 let(:parent) { find_matching(cursor_cxx) { |child, parent| 441 child.kind == :cursor_cxx_method and child.spelling == 'func_d' and parent.spelling != 'D' } } 442 443 it 'returns translation unit as lexical parent' do 444 expect(parent.lexical_parent.kind).to eq(:cursor_translation_unit) 445 end 446 end 447 448 describe '#included_file' do 449 #TODO 450 end 451 452 describe '#definition?' do 453 let (:struct) { find_all(cursor_canon, :cursor_struct).at(2) } 454 455 it "checks cursor is a definition" do 456 expect(struct.definition?).to be true 457 end 458 end 459 460 describe '#usr' do 461 let (:func) { find_first(cursor, :cursor_function) } 462 463 it "returns something in string" do 464 expect(func.usr).to be_kind_of(String) 465 end 466 end 467 468 describe '#variadic?' do 469 let(:func) { find_matching(cursor_cxx) { |child, parent| 470 child.kind == :cursor_function and child.spelling == 'f_variadic' } } 471 472 it "checks cursor is a variadic function" do 473 expect(func.variadic?).to be true 474 end 475 end 476 477 describe '#referenced' do 478 let(:struct) { find_matching(cursor_cxx) { |child, parent| 479 child.kind == :cursor_struct and child.spelling == 'A' } } 480 let(:ref) { find_matching(cursor_cxx) { |child, parent| 481 child.kind == :cursor_type_ref and child.spelling == 'struct A' } } 482 483 it "returns a cursor that this cursor references" do 484 expect(ref.referenced).to eq(struct) 485 end 486 487 end 488 489 describe '#hash' do 490 let (:func) { find_first(cursor, :cursor_function) } 491 492 it "computes hash for the cursor" do 493 expect(func.hash).to be_kind_of(Fixnum) 494 end 495 end 496 497 describe '#availability' do 498 let (:func) { find_first(cursor, :cursor_function) } 499 500 it "returns :available for the cursor availability" do 501 expect(func.availability).to equal(:available) 502 end 503 end 504 505 describe '#type' do 506 let (:field) { find_first(cursor, :cursor_field_decl) } 507 508 it "returns type for the cursor" do 509 expect(field.type).to be_kind_of(Type) 510 expect(field.type.kind).to equal(:type_int) 511 end 512 end 513 514 describe '#underlying_type' do 515 let (:typedef) { find_first(cursor_cxx, :cursor_typedef_decl) } 516 517 it "returns type that the cursor type is underlying" do 518 expect(typedef.underlying_type).to be_kind_of(Type) 519 expect(typedef.underlying_type.kind).to equal(:type_pointer) 520 end 521 end 522 523 describe '#bitfield?' do 524 let(:bitfield) { find_matching(cursor_cxx) { |child, parent| 525 child.kind == :cursor_field_decl and child.spelling == 'bit_field_a' } } 526 let(:non_bitfield) { find_matching(cursor_cxx) { |child, parent| 527 child.kind == :cursor_field_decl and child.spelling == 'non_bit_field_c' } } 528 529 it "returns true if the cursor is bitfield" do 530 expect(bitfield.bitfield?).to be true 531 end 532 533 it "returns false if the cursor is not bitfield" do 534 expect(non_bitfield.bitfield?).to be false 535 end 536 end 537 538 describe '#bitwidth' do 539 let(:bitfield) { find_matching(cursor_cxx) { |child, parent| 540 child.kind == :cursor_field_decl and child.spelling == 'bit_field_a' } } 541 let(:non_bitfield) { find_matching(cursor_cxx) { |child, parent| 542 child.kind == :cursor_field_decl and child.spelling == 'non_bit_field_c' } } 543 544 it "returns the bit width of the bit field if the cursor is bitfield" do 545 expect(bitfield.bitwidth).to be_kind_of(Integer) 546 expect(bitfield.bitwidth).to eq(2) 547 end 548 549 it "returns -1 if the cursor is not bitfield" do 550 expect(non_bitfield.bitwidth).to eq(-1) 551 end 552 end 553 554 describe '#enum_decl_integer_type' do 555 let(:enum) { find_matching(cursor_cxx) { |child, parent| 556 child.kind == :cursor_enum_decl and child.spelling == 'normal_enum' } } 557 558 it "returns the integer type of the enum declaration" do 559 expect(enum.enum_decl_integer_type).to be_kind_of(Type) 560 expect(enum.enum_decl_integer_type.kind).to be(:type_uint) 561 end 562 end 563 564 describe '#platform_availability' do 565 let(:func) { find_matching(cursor_cxx) { |child, parent| 566 child.kind == :cursor_function and child.spelling == 'availability_func'} } 567 let(:availability) { func.platform_availability } 568 569 it "returns the availability of the entity as Hash" do 570 expect(availability).to be_kind_of(Hash) 571 expect(availability[:always_deprecated]).to be_kind_of(Integer) 572 expect(availability[:always_unavailable]).to be_kind_of(Integer) 573 expect(availability[:deprecated_message]).to be_kind_of(String) 574 expect(availability[:unavailable_message]).to be_kind_of(String) 575 expect(availability[:availability]).to be_kind_of(Array) 576 end 577 end 578 579 describe '#overriddens' do 580 let(:override_cursor) { find_matching(cursor_cxx) { |child, parent| 581 child.kind == :cursor_cxx_method and 582 child.spelling == 'func_a' and parent.spelling == 'D' } } 583 584 it "returns the set of methods which are overridden by this cursor method" do 585 expect(override_cursor.overriddens).to be_kind_of(Array) 586 expect(override_cursor.overriddens.size).to eq(2) 587 expect(override_cursor.overriddens.map{|cur| cur.semantic_parent.spelling}).to eq(["B", "C"]) 588 end 589 end 590 591 describe '#overloaded_decl' do 592 let(:overloaded) { find_matching(cursor_cxx) { |child, parent| 593 child.kind == :cursor_overloaded_decl_ref and child.spelling == 'func_overloaded' } } 594 595 it "returns a cursor for one of the overloaded declarations" do 596 expect(overloaded.overloaded_decl(0)).to be_kind_of(Cursor) 597 expect(overloaded.overloaded_decl(0).kind).to be(:cursor_function_template) 598 expect(overloaded.overloaded_decl(0).spelling).to eq('func_overloaded') 599 end 600 end 601 602 describe '#num_overloaded_decls' do 603 let(:overloaded) { find_matching(cursor_cxx) { |child, parent| 604 child.kind == :cursor_overloaded_decl_ref and child.spelling == 'func_overloaded' } } 605 606 it "returns the number of overloaded declarations" do 607 expect(overloaded.num_overloaded_decls).to be_kind_of(Integer) 608 expect(overloaded.num_overloaded_decls).to be(2) 609 end 610 end 611 612 describe '#objc_type_encoding' do 613 #TODO 614 end 615 616 describe '#argument' do 617 let(:func) { find_matching(cursor_cxx) { |child, parent| 618 child.kind == :cursor_function and child.spelling == 'f_non_variadic' } } 619 620 it "returns the argument cursor of the function" do 621 expect(func.argument(0)).to be_kind_of(Cursor) 622 expect(func.argument(0).spelling).to eq('a') 623 end 624 end 625 626 describe '#num_arguments' do 627 let(:cursor_cxx) { Index.new.parse_translation_unit(fixture_path("test.cxx")).cursor } 628 let(:func) { find_matching(cursor_cxx) { |child, parent| 629 child.kind == :cursor_function and child.spelling == 'f_non_variadic' } } 630 631 it "returns the number of non-variadic arguments" do 632 expect(func.num_arguments).to be_kind_of(Integer) 633 expect(func.num_arguments).to be(3) 634 end 635 end 636 637 describe '#result_type' do 638 let(:func) { find_matching(cursor_cxx) { |child, parent| 639 child.kind == :cursor_function and child.spelling == 'f_non_variadic' } } 640 641 it "result the result type of the function" do 642 expect(func.result_type).to be_kind_of(Type) 643 expect(func.result_type.kind).to be(:type_void) 644 end 645 end 646 647 describe '#raw_comment_text' do 648 let(:func) { find_matching(cursor_pp) { |child, parent| 649 child.kind == :cursor_function and child.spelling == 'a_function' } } 650 651 it "checks the cursor is declaration" do 652 expect(func.raw_comment_text).to be_kind_of(String) 653 expect(func.raw_comment_text).not_to be_empty 654 end 655 end 656 657 describe '#comment' do 658 let(:func) { find_matching(cursor_pp) { |child, parent| 659 child.kind == :cursor_function and child.spelling == 'a_function' } } 660 661 it "checks the cursor is declaration" do 662 expect(func.comment).to be_kind_of(Comment) 663 end 664 end 665 666 describe '#included_file' do 667 let (:inclusion) { find_first(cursor_pp, :cursor_inclusion_directive) } 668 669 it 'returns the file that is included by the given inclusion directive cursor' do 670 expect(inclusion.included_file).to be_kind_of(FFI::Clang::File) 671 expect(File.basename(inclusion.included_file.name)).to eq("docs.h") 672 end 673 end 674 675 describe '#references' do 676 let (:struct_cursor) { find_first(cursor_canon, :cursor_struct) } 677 let (:unspecified_references) { struct_cursor.references } 678 let (:specified_references) { struct_cursor.references(fixture_path("canonical.c")) } 679 680 it "returns an Array of reference Cursors in the main file" do 681 expect(unspecified_references).to be_kind_of(Array) 682 expect(unspecified_references.length).not_to equal(0) 683 expect(unspecified_references).to all(be_a (FFI::Clang::Cursor)) 684 end 685 686 it "returns an Array of reference Cursors in the specified file" do 687 expect(specified_references).to be_kind_of(Array) 688 expect(specified_references.length).not_to equal(0) 689 expect(specified_references).to all(be_a (FFI::Clang::Cursor)) 690 end 691 end 692 693 describe Cursor::PlatformAvailability do 694 let(:func) { find_matching(cursor_cxx) { |child, parent| 695 child.kind == :cursor_function and child.spelling == 'availability_func'} } 696 let(:availability) { func.platform_availability[:availability].first } 697 698 it "can be obtained by Cursor#platform_availability" do 699 expect(availability).to be_kind_of(Cursor::PlatformAvailability) 700 end 701 702 describe "#platform" do 703 it "returns availability information for the platform" do 704 expect(availability.platform).to be_kind_of(String) 705 end 706 end 707 708 describe "#introduced" do 709 it "returns the version number in which this entity was introduced" do 710 expect(availability.introduced).to be_kind_of(Lib::CXVersion) 711 expect(availability.introduced.to_s).to eq("10.4.1") 712 end 713 end 714 715 describe "#deprecated" do 716 it "returns the version number in which this entity was deprecated" do 717 expect(availability.deprecated).to be_kind_of(Lib::CXVersion) 718 expect(availability.deprecated.to_s).to eq("10.6") 719 end 720 end 721 722 describe "#obsoleted" do 723 it "returns the version number in which this entity was obsoleted" do 724 expect(availability.obsoleted).to be_kind_of(Lib::CXVersion) 725 expect(availability.obsoleted.to_s).to eq("10.7") 726 end 727 end 728 729 describe "#unavailable" do 730 it "returns whether the entity is unavailable on this platform" do 731 expect(availability.unavailable).to be false 732 end 733 end 734 735 describe "#message" do 736 it "returns an optional message to provide to a user of this API" do 737 expect(availability.message).to be_kind_of(String) 738 end 739 end 740 end 741 end