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