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

comment_spec.rb (15367B)


      1 # -*- coding: utf-8 -*-
      2 # Copyright, 2013, by Carlos Martín Nieto <cmn@dwim.me>
      3 # 
      4 # Permission is hereby granted, free of charge, to any person obtaining a copy
      5 # of this software and associated documentation files (the "Software"), to deal
      6 # in the Software without restriction, including without limitation the rights
      7 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      8 # copies of the Software, and to permit persons to whom the Software is
      9 # furnished to do so, subject to the following conditions:
     10 # 
     11 # The above copyright notice and this permission notice shall be included in
     12 # all copies or substantial portions of the Software.
     13 # 
     14 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     17 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     18 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     19 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     20 # THE SOFTWARE.
     21 
     22 describe Comment do
     23 	let(:cursor) { Index.new.parse_translation_unit(fixture_path("docs.cc")).cursor }
     24 	let (:comment) { find_first(cursor, :cursor_function).comment }
     25 
     26 	it "can be obtained from a cursor" do
     27 		expect(comment).to be_kind_of(Comment)
     28 		expect(comment).to be_kind_of(FullComment)
     29 		expect(comment.kind).to equal(:comment_full)
     30 	end
     31 
     32 	it "can parse the brief description" do
     33 		para = comment.child
     34 		expect(para.kind).to equal(:comment_paragraph)
     35 		expect(para).to be_kind_of(ParagraphComment)
     36 		text = para.child
     37 		expect(text.kind).to equal(:comment_text)
     38 		expect(text).to be_kind_of(TextComment)
     39 		expect(text.text.strip).to eq("Short explanation")
     40 	end
     41 
     42 	it "can parse the longer description" do
     43 		para = comment.child(1)
     44 		expect(para.kind).to equal(:comment_paragraph)
     45 		expect(para.num_children).to equal(2)
     46 
     47 		lines = (0..para.num_children-1).map do |i|
     48 			para.child(i).text
     49 		end
     50 
     51 		expect(lines).to eq([" This is a longer explanation",
     52 				 " that spans multiple lines"])
     53 	end
     54 
     55 	it "has working helpers" do
     56 		expect(comment.num_children).to equal(8)
     57 
     58 		para = comment.child(1)
     59 		expect(para.text).to eq(" This is a longer explanation\n that spans multiple lines")
     60 	end
     61 
     62 	it "understands params" do
     63 		[['input', " some input\n "], ['flags', " some flags\n "]].each_with_index do |v, child_idx|
     64 			param = comment.child(3 + child_idx)
     65 			expect(param).to be_kind_of(ParamCommandComment)
     66 
     67 			expect(param.valid_index?).to be_truthy
     68 			expect(param.index).to be == child_idx
     69 			expect(param.name).to be == v[0]
     70 			expect(param.child.text).to be == v[1]
     71 			expect(param.comment).to be == v[1]
     72 		end
     73 	end
     74 
     75 	describe "#whitespace?" do
     76 		it "checks the comment is whitespace" do
     77 			expect(comment.child.whitespace?).to be false
     78 		end
     79 	end
     80 
     81 	describe "#has_trailing_newline?" do
     82 		it "checks the content has a traling newline" do
     83 			expect(comment.child.has_trailing_newline?).to be false
     84 		end
     85 	end
     86 
     87 	context 'comment_null' do
     88 		let(:comment_cursor) { find_matching(cursor) { |child, parent|
     89 				child.kind == :cursor_function and child.spelling == 'no_comment_function' } }
     90 		let(:comment) { comment_cursor.comment }
     91 
     92 		it "is null comment" do
     93 			expect(comment).to be_kind_of(Comment)
     94 			expect(comment.kind).to eq(:comment_null)
     95 			expect(comment.text).to eq('')
     96 		end
     97 	end
     98 
     99 	context 'unknown comment type' do
    100 		let(:comment) { 'foobar' }
    101 		it "raises NotImplementedError" do
    102 			expect(Lib).to receive(:comment_get_kind).with(comment).and_return(:xxx_yyy_zzzz)
    103 			expect{Comment.build_from(comment)}.to raise_error(NotImplementedError)
    104 		end
    105 	end
    106 
    107 	describe HTMLStartTagComment do
    108 		let(:comment_cursor) { find_matching(cursor) { |child, parent|
    109 				child.kind == :cursor_function and child.spelling == 'b_function' } }
    110 		let(:comment) { comment_cursor.comment }
    111 		let(:paragraph) { comment_cursor.comment.child }
    112 		let(:html_start_tag_comments) { paragraph.children.select{|c| c.kind == :comment_html_start_tag} }
    113 
    114 		it "can be obtained from cursor" do
    115 			expect(comment).to be_kind_of(FullComment)
    116 			expect(comment.kind).to equal(:comment_full)
    117 			expect(paragraph).to be_kind_of(ParagraphComment)
    118 			expect(html_start_tag_comments.first).to be_kind_of(HTMLStartTagComment)
    119 			expect(html_start_tag_comments.size).to eq(2)
    120 		end
    121 
    122 		describe "#tag" do
    123 			it "returns HTML tag name" do
    124 				expect(html_start_tag_comments[0].tag).to eq('br')
    125 				expect(html_start_tag_comments[1].tag).to eq('a')
    126 			end
    127 
    128 			it "is alias method of #name" do
    129 				expect(html_start_tag_comments[0].name).to eq('br')
    130 				expect(html_start_tag_comments[1].name).to eq('a')
    131 			end
    132 		end
    133 
    134 		describe "#text" do
    135 			it "returns HTML tag as string" do
    136 				expect(html_start_tag_comments[0].text.strip).to eq('<br/>')
    137 				expect(html_start_tag_comments[1].text.strip).to eq('<a href="http://example.org/">')
    138 			end
    139 		end
    140 
    141 		describe "#self_closing?" do
    142 			it "checks the tag is self-closing" do
    143 				expect(html_start_tag_comments[0].self_closing?).to be true
    144 				expect(html_start_tag_comments[1].self_closing?).to be false
    145 			end
    146 		end
    147 
    148 		describe "#num_attrs" do
    149 			it "returns the number of attributes" do
    150 				expect(html_start_tag_comments[0].num_attrs).to eq(0)
    151 				expect(html_start_tag_comments[1].num_attrs).to eq(1)
    152 			end
    153 		end
    154 
    155 		describe "#attrs" do
    156 			it "returns attributes as Array of Hash" do
    157 				expect(html_start_tag_comments[0].attrs).to eq([])
    158                 expect(html_start_tag_comments[1].attrs).to eq([{name: 'href', value: 'http://example.org/'}])
    159 			end
    160 		end
    161 	end
    162 
    163 	describe HTMLEndTagComment do
    164 		let(:comment_cursor) { find_matching(cursor) { |child, parent|
    165 				child.kind == :cursor_function and child.spelling == 'b_function' } }
    166 		let(:comment) { comment_cursor.comment }
    167 		let(:paragraph) { comment_cursor.comment.child }
    168 		let(:html_end_tag_comment) { paragraph.children.select{|c| c.kind == :comment_html_end_tag}.first }
    169 
    170 		it "can be obtained from cursor" do
    171 			expect(comment).to be_kind_of(FullComment)
    172 			expect(comment.kind).to equal(:comment_full)
    173 			expect(paragraph).to be_kind_of(ParagraphComment)
    174 			expect(html_end_tag_comment).to be_kind_of(HTMLEndTagComment)
    175 		end
    176 
    177 		describe "#tag" do
    178 			it "returns HTML tag name" do
    179 				expect(html_end_tag_comment.tag).to eq('a')
    180 			end
    181 
    182 			it "is alias method of #name" do
    183 				expect(html_end_tag_comment.name).to eq('a')
    184 			end
    185 		end
    186 
    187 		describe "#text" do
    188 			it "returns HTML tag as string" do
    189 				expect(html_end_tag_comment.text.strip).to eq('</a>')
    190 			end
    191 		end
    192 	end
    193 
    194 	describe FullComment do
    195 		let(:comment_cursor) { find_matching(cursor) { |child, parent|
    196 				child.kind == :cursor_function and child.spelling == 'f_function' } }
    197 		let(:comment) { comment_cursor.comment }
    198 
    199 		it "can be obtained from cursor" do
    200 			expect(comment).to be_kind_of(FullComment)
    201 			expect(comment.kind).to equal(:comment_full)
    202 		end
    203 
    204 		describe "#to_html" do
    205 			it "converts a given full parsed comment to an HTML fragment" do
    206 				expect(comment.to_html).to be_kind_of(String)
    207 				expect(comment.to_html).to eq('<p class="para-brief"> this is a function.</p>')
    208 			end
    209 		end
    210 
    211 		describe "#to_xml" do
    212 			it "converts a given full parsed comment to an XML document" do
    213 				expect(comment.to_xml).to be_kind_of(String)
    214 			end
    215 		end
    216 	end
    217 
    218 	describe BlockCommandComment do
    219 		let(:comment_cursor) { find_matching(cursor) { |child, parent|
    220 				child.kind == :cursor_function and child.spelling == 'f_function' } }
    221 		let(:comment) { comment_cursor.comment }
    222 		let(:block_cmd_comment) { comment.children.select{|c| c.kind == :comment_block_command}.first }
    223 
    224 		it "can be obtained from cursor" do
    225 			expect(comment).to be_kind_of(FullComment)
    226 			expect(comment.kind).to equal(:comment_full)
    227 			expect(block_cmd_comment).to be_kind_of(BlockCommandComment)
    228 			expect(block_cmd_comment.child).to be_kind_of(ParagraphComment)
    229 		end
    230 
    231 		describe "#name" do
    232 			it "returns the name of the block command" do
    233 				expect(block_cmd_comment.name).to eq("brief")
    234 			end
    235 		end
    236 
    237 		describe "#paragraph" do
    238 			it "returns the paragraph" do
    239 				expect(block_cmd_comment.paragraph).to be_kind_of(ParagraphComment)
    240 			end
    241 		end
    242 
    243 		describe "#num_args" do
    244 			it "returns the number of word-like arguments" do
    245 				expect(block_cmd_comment.num_args).to eq(0)
    246 			end
    247 		end
    248 
    249 		describe "#args" do
    250 			it "returns word-like arguments" do
    251 				expect(block_cmd_comment.args).to be_kind_of(Array)
    252 				expect(block_cmd_comment.args).to eq([])
    253 			end
    254 
    255 			#TODO: needs tests with comments which have arguments
    256 		end
    257 
    258 		describe "#text" do
    259 			it "returns readble text that includes children's comments" do
    260 				expect(block_cmd_comment.text).to be_kind_of(String)
    261 				expect(block_cmd_comment.text.strip).to eq('this is a function.')
    262 			end
    263 
    264 			it "is a alias method of #comment" do
    265 				expect(block_cmd_comment.comment).to eq(block_cmd_comment.text)
    266 			end
    267 		end
    268 	end
    269 
    270 	describe InlineCommandComment do
    271 		let(:comment_cursor) { find_matching(cursor) { |child, parent|
    272 				child.kind == :cursor_function and child.spelling == 'd_function' } }
    273 		let(:comment) { comment_cursor.comment }
    274 		let(:inline_command_comments) { comment.child.children.select{|c| c.kind == :comment_inline_command} }
    275 
    276 		it "can be obtained from cursor" do
    277 			expect(comment).to be_kind_of(FullComment)
    278 			expect(comment.kind).to equal(:comment_full)
    279 			expect(comment.child).to be_kind_of(ParagraphComment)
    280 			expect(inline_command_comments.size).to eq(2)
    281 		end
    282 
    283 		describe "#name" do
    284 			it "returns the name of the inline command" do
    285 				expect(inline_command_comments[0].name).to eq("em")
    286 				expect(inline_command_comments[1].name).to eq("b")
    287 			end
    288 		end
    289 
    290 		describe "#render_kind" do
    291 			it "returns the most appropriate rendering mode" do
    292 				expect(inline_command_comments[0].render_kind).to eq(:emphasized)
    293 				expect(inline_command_comments[1].render_kind).to eq(:bold)
    294 			end
    295 		end
    296 
    297 		describe "#num_args" do
    298 			it "returns number of command arguments" do
    299 				expect(inline_command_comments[0].num_args).to eq(1)
    300 				expect(inline_command_comments[1].num_args).to eq(1)
    301 			end
    302 		end
    303 
    304 		describe "#args" do
    305 			it "returns arguments as Array" do
    306 				expect(inline_command_comments[0].args).to eq(["foo"])
    307 				expect(inline_command_comments[1].args).to eq(["bar"])
    308 			end
    309 		end
    310 
    311 		describe "#text" do
    312 			it "returns readble text" do
    313 				expect(inline_command_comments[0].text.strip).to eq("foo")
    314 				expect(inline_command_comments[1].text.strip).to eq("bar")
    315 			end
    316 		end
    317 	end
    318 
    319 	describe VerbatimBlockCommandComment do
    320 		let(:comment_cursor) { find_matching(cursor) { |child, parent|
    321 				child.kind == :cursor_function and child.spelling == 'e_function' } }
    322 		let(:comment) { comment_cursor.comment }
    323 		let(:verb_block_cmd_comment) { comment.children.select{|c| c.kind == :comment_verbatim_block_command}.first }
    324 
    325 		it "can be obtained from cursor" do
    326 			expect(comment).to be_kind_of(FullComment)
    327 			expect(comment.kind).to equal(:comment_full)
    328 			expect(verb_block_cmd_comment).to be_kind_of(VerbatimBlockCommandComment)
    329 		end
    330 
    331 		describe "#text" do
    332 			it "returns readble text" do
    333 				expect(verb_block_cmd_comment.text).to eq("  foo bar\n  baz")
    334 			end
    335 		end
    336 	end
    337 
    338 	describe VerbatimBlockLineComment do
    339 		let(:comment_cursor) { find_matching(cursor) { |child, parent|
    340 				child.kind == :cursor_function and child.spelling == 'e_function' } }
    341 		let(:comment) { comment_cursor.comment }
    342 		let(:verb_block_cmd_comment) { comment.children.select{|c| c.kind == :comment_verbatim_block_command}.first }
    343 		let(:verb_block_line_comments) { verb_block_cmd_comment.children }
    344 
    345 		it "can be obtained from cursor" do
    346 			expect(comment).to be_kind_of(FullComment)
    347 			expect(comment.kind).to equal(:comment_full)
    348 			expect(verb_block_cmd_comment).to be_kind_of(VerbatimBlockCommandComment)
    349 			expect(verb_block_line_comments.first).to be_kind_of(VerbatimBlockLineComment)
    350 			expect(verb_block_line_comments.size).to eq(2)
    351 		end
    352 
    353 		describe "#text" do
    354 			it "returns readble text" do
    355 				expect(verb_block_line_comments[0].text.strip).to eq("foo bar")
    356 				expect(verb_block_line_comments[1].text.strip).to eq("baz")
    357 			end
    358 		end
    359 	end
    360 
    361 	describe VerbatimLine do
    362 	# TODO: how to generate this comment?
    363 	end
    364 
    365 	describe ParamCommandComment do
    366 		let(:comment_cursor) { find_matching(cursor) { |child, parent|
    367 				child.kind == :cursor_function and child.spelling == 'a_function' } }
    368 		let(:comment) { comment_cursor.comment }
    369 		let(:param_cmd_comments) { comment.children.select{|c| c.kind == :comment_param_command} }
    370 
    371 		it "can be obtained from cursor" do
    372 			expect(comment).to be_kind_of(FullComment)
    373 			expect(comment.kind).to equal(:comment_full)
    374 			expect(param_cmd_comments.first).to be_kind_of(ParamCommandComment)
    375 			expect(param_cmd_comments.size).to eq(4)
    376 		end
    377 
    378 		describe "#text" do
    379 			it "returns readble text" do
    380 				expect(param_cmd_comments[0].text.strip).to eq("some input")
    381 				expect(param_cmd_comments[1].text.strip).to eq("some flags")
    382 			end
    383 		end
    384 
    385 		describe "#direction_explicit?" do
    386 			it "checks the direction is specified explicitly" do
    387 				expect(param_cmd_comments[0].direction_explicit?).to be true
    388 				expect(param_cmd_comments[3].direction_explicit?).to be false
    389 			end
    390 		end
    391 
    392 		describe "#direction" do
    393 			it "returns parameter passing direction" do
    394 				expect(param_cmd_comments[0].direction).to eq(:pass_direction_in)
    395 				expect(param_cmd_comments[1].direction).to eq(:pass_direction_out)
    396 				expect(param_cmd_comments[2].direction).to eq(:pass_direction_inout)
    397 				expect(param_cmd_comments[3].direction).to eq(:pass_direction_in)
    398 			end
    399 		end
    400 	end
    401 
    402 	describe TParamCommandComment do
    403 		let(:comment_cursor) { find_matching(cursor) { |child, parent|
    404 				child.kind == :cursor_function_template and child.spelling == 'c_function' } }
    405 		let(:comment) { comment_cursor.comment }
    406 		let(:tparam_cmd_comments) { comment.children.select{|c| c.kind == :comment_tparam_command} }
    407 
    408 		it "can be obtained from cursor" do
    409 			expect(comment).to be_kind_of(FullComment)
    410 			expect(comment.kind).to equal(:comment_full)
    411 			expect(tparam_cmd_comments.first).to be_kind_of(TParamCommandComment)
    412 			expect(tparam_cmd_comments.size).to eq(3)
    413 		end
    414 
    415 		describe "#text" do
    416 			it "returns readble text" do
    417 				expect(tparam_cmd_comments[0].text.strip).to eq("some type of foo")
    418 				expect(tparam_cmd_comments[1].text.strip).to eq("some type of bar")
    419 			end
    420 		end
    421 
    422 		describe "#name" do
    423 			it "returns template parameter name" do
    424 				expect(tparam_cmd_comments[0].name).to eq("T1")
    425 				expect(tparam_cmd_comments[1].name).to eq("T2")
    426 				expect(tparam_cmd_comments[2].name).to eq("T3")
    427 			end
    428 		end
    429 
    430 		describe "#valid_position?" do
    431 			it "checks this parameter has valid position" do
    432 				expect(tparam_cmd_comments[0].valid_position?).to be true
    433 			end
    434 		end
    435 
    436 		describe "#depth" do
    437 			it "returns nesting depth of this parameter" do
    438 				expect(tparam_cmd_comments[0].depth).to eq(1)
    439 				expect(tparam_cmd_comments[1].depth).to eq(2)
    440 				expect(tparam_cmd_comments[2].depth).to eq(1)
    441 			end
    442 		end
    443 
    444 		describe "#index" do
    445 			it "returns index of the parameter at the given nesting depth" do
    446 				expect(tparam_cmd_comments[0].index(0)).to eq(0)
    447 				expect(tparam_cmd_comments[1].index(0)).to eq(1)
    448 				expect(tparam_cmd_comments[1].index(1)).to eq(0)
    449 				expect(tparam_cmd_comments[2].index(0)).to eq(1)
    450 			end
    451 		end
    452 	end
    453 end