ffi-clang

FORK: Ruby FFI bindings for my custom patched clang 8.0.
git clone https://git.neptards.moe/neptards/ffi-clang.git
Log | Files | Refs | README

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