yard 0.2.3 → 0.2.3.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of yard might be problematic. Click here for more details.
- data/.yardopts +12 -0
- data/README.markdown +20 -2
- data/Rakefile +3 -2
- data/lib/rubygems_plugin.rb +91 -0
- data/lib/yard.rb +2 -1
- data/lib/yard/cli/yardoc.rb +41 -9
- data/lib/yard/code_objects/base.rb +2 -12
- data/lib/yard/docstring.rb +19 -8
- data/lib/yard/generators/full_doc_generator.rb +2 -1
- data/lib/yard/generators/helpers/html_helper.rb +6 -2
- data/lib/yard/generators/tags_generator.rb +23 -2
- data/lib/yard/handlers/base.rb +6 -5
- data/lib/yard/parser/ruby/ast_node.rb +2 -1
- data/lib/yard/parser/ruby/legacy/ruby_lex.rb +9 -1
- data/lib/yard/parser/ruby/legacy/statement.rb +24 -16
- data/lib/yard/parser/ruby/legacy/statement_list.rb +82 -13
- data/lib/yard/parser/ruby/legacy/token_list.rb +10 -2
- data/lib/yard/parser/ruby/ruby_parser.rb +1 -0
- data/lib/yard/parser/source_parser.rb +1 -5
- data/lib/yard/tags/library.rb +1 -1
- data/lib/yard/tags/overload_tag.rb +1 -0
- data/spec/cli/yardoc_spec.rb +33 -0
- data/spec/docstring_spec.rb +24 -0
- data/spec/generators/helpers/html_helper_spec.rb +104 -102
- data/spec/handlers/ruby/legacy/base_spec.rb +25 -0
- data/spec/parser/examples/parse_in_order_001.rb.txt +2 -0
- data/spec/parser/examples/parse_in_order_002.rb.txt +2 -0
- data/spec/parser/ruby/ast_node_spec.rb +13 -9
- data/spec/parser/ruby/legacy/statement_list_spec.rb +122 -44
- data/spec/parser/ruby/legacy/token_list_spec.rb +57 -23
- data/spec/parser/ruby/ruby_parser_spec.rb +53 -0
- data/spec/parser/source_parser_spec.rb +59 -16
- data/spec/spec_helper.rb +2 -4
- data/spec/tags/library_spec.rb +23 -0
- data/templates/default/deprecated/html/main.erb +5 -3
- data/templates/default/fulldoc/html/all_methods.erb +1 -1
- data/templates/default/fulldoc/html/all_namespaces.erb +1 -1
- data/templates/default/fulldoc/html/custom.css +1 -0
- data/templates/default/fulldoc/html/file.erb +1 -0
- data/templates/default/fulldoc/html/footer.erb +5 -0
- data/templates/default/fulldoc/html/header.erb +1 -0
- data/templates/default/fulldoc/html/html_head.erb +1 -0
- data/templates/default/fulldoc/html/index.erb +1 -1
- data/templates/default/fulldoc/html/style.css +6 -0
- data/templates/default/tags/html/see.erb +1 -1
- metadata +13 -5
@@ -9,8 +9,9 @@ module YARD
|
|
9
9
|
|
10
10
|
class AstNode < Array
|
11
11
|
attr_accessor :type, :parent, :docstring, :file, :full_source, :source
|
12
|
-
attr_accessor :source_range, :line_range
|
12
|
+
attr_accessor :source_range, :line_range, :docstring_range
|
13
13
|
alias comments docstring
|
14
|
+
alias comments_range docstring_range
|
14
15
|
alias to_s source
|
15
16
|
|
16
17
|
KEYWORDS = { class: true, alias: true, lambda: true, do_block: true,
|
@@ -11,7 +11,7 @@ module YARD
|
|
11
11
|
EXPR_FNAME = :EXPR_FNAME
|
12
12
|
EXPR_DOT = :EXPR_DOT
|
13
13
|
EXPR_CLASS = :EXPR_CLASS
|
14
|
-
|
14
|
+
|
15
15
|
class Token
|
16
16
|
NO_TEXT = "??".freeze
|
17
17
|
attr :text
|
@@ -32,6 +32,14 @@ module YARD
|
|
32
32
|
attr_reader :line_no, :char_no, :text
|
33
33
|
attr_accessor :lex_state
|
34
34
|
end
|
35
|
+
|
36
|
+
class TkBlockContents < Token
|
37
|
+
def text; '...' end
|
38
|
+
end
|
39
|
+
|
40
|
+
class TkStatementEnd < Token
|
41
|
+
def text; '' end
|
42
|
+
end
|
35
43
|
|
36
44
|
class TkNode < Token
|
37
45
|
attr :node
|
@@ -2,6 +2,7 @@ module YARD
|
|
2
2
|
module Parser::Ruby::Legacy
|
3
3
|
class Statement
|
4
4
|
attr_reader :tokens, :comments, :block
|
5
|
+
attr_accessor :comments_range
|
5
6
|
|
6
7
|
def initialize(tokens, block = nil, comments = nil)
|
7
8
|
@tokens = tokens
|
@@ -9,16 +10,22 @@ module YARD
|
|
9
10
|
@comments = comments
|
10
11
|
end
|
11
12
|
|
13
|
+
def first_line
|
14
|
+
to_s(false)
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s(include_block = true)
|
18
|
+
tokens.map do |token|
|
19
|
+
RubyToken::TkBlockContents === token ? block.to_s : token.text
|
20
|
+
end.join
|
21
|
+
end
|
22
|
+
alias source to_s
|
23
|
+
|
12
24
|
def inspect
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
else
|
18
|
-
buf.last << tk.text
|
19
|
-
end
|
20
|
-
end
|
21
|
-
buf.map {|text| "\t#{line}: #{text}" }.join("\n")
|
25
|
+
l = line - 1
|
26
|
+
to_s.split(/\n/).map do |text|
|
27
|
+
"\t#{l += 1}: #{text}"
|
28
|
+
end.join("\n")
|
22
29
|
end
|
23
30
|
alias show inspect
|
24
31
|
|
@@ -27,14 +34,15 @@ module YARD
|
|
27
34
|
end
|
28
35
|
|
29
36
|
private
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
+
|
38
|
+
def clean_tokens(tokens)
|
39
|
+
last_tk = nil
|
40
|
+
tokens.reject do |tk|
|
41
|
+
tk.is_a?(RubyToken::TkNL) ||
|
42
|
+
(last_tk.is_a?(RubyToken::TkSPACE) &&
|
43
|
+
last_tk.class == tk.class) && last_tk = tk
|
37
44
|
end
|
45
|
+
end
|
38
46
|
end
|
39
47
|
end
|
40
48
|
end
|
@@ -42,8 +42,10 @@ module YARD
|
|
42
42
|
@state = :first_statement
|
43
43
|
@statement_stack = []
|
44
44
|
@level = 0
|
45
|
+
@block_num = 0
|
45
46
|
@done = false
|
46
47
|
@current_block = nil
|
48
|
+
@comments_line = nil
|
47
49
|
@statement, @block, @comments = TokenList.new, nil, nil
|
48
50
|
@last_tk, @last_ns_tk, @before_last_tk = nil, nil, nil
|
49
51
|
|
@@ -59,17 +61,56 @@ module YARD
|
|
59
61
|
# If there is no code in the block, return nil
|
60
62
|
@comments = @comments.compact if @comments
|
61
63
|
if @block || !@statement.empty?
|
62
|
-
|
64
|
+
sanitize_statement_end
|
65
|
+
sanitize_block
|
66
|
+
@statement.pop if [TkNL, TkSPACE, TkSEMICOLON].include?(@statement.last.class)
|
67
|
+
stmt = Statement.new(@statement, @block, @comments)
|
68
|
+
if @comments && @comments_line
|
69
|
+
stmt.comments_range = (@comments_line..(@comments_line + @comments.size - 1))
|
70
|
+
end
|
71
|
+
stmt
|
63
72
|
else
|
64
73
|
nil
|
65
74
|
end
|
66
75
|
end
|
76
|
+
|
77
|
+
def sanitize_statement_end
|
78
|
+
extra = []
|
79
|
+
(@statement.size - 1).downto(0) do |index|
|
80
|
+
token = @statement[index]
|
81
|
+
if TkStatementEnd === token
|
82
|
+
while [TkNL, TkSPACE, TkSEMICOLON].include?(@statement[index - 1].class)
|
83
|
+
extra.unshift(@statement.delete_at(index - 1))
|
84
|
+
index -= 1
|
85
|
+
end
|
86
|
+
@statement.insert(index + 1, *extra)
|
87
|
+
return
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def sanitize_block
|
93
|
+
return unless @block
|
94
|
+
extra = []
|
95
|
+
while [TkSPACE, TkNL, TkSEMICOLON].include?(@block.last.class)
|
96
|
+
next(@block.pop) if TkSEMICOLON === @block.last
|
97
|
+
extra.unshift(@block.pop)
|
98
|
+
end
|
99
|
+
|
100
|
+
@statement.each_with_index do |token, index|
|
101
|
+
if TkBlockContents === token
|
102
|
+
@statement[index, 1] = [token, *extra]
|
103
|
+
return
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
67
107
|
|
68
108
|
##
|
69
109
|
# Processes a single token
|
70
110
|
#
|
71
111
|
# @param [RubyToken::Token] tk the token to process
|
72
112
|
def process_token(tk)
|
113
|
+
#p tk.text, @state, @level, @current_block, "<br/>"
|
73
114
|
case @state
|
74
115
|
when :first_statement
|
75
116
|
return if process_initial_comment(tk)
|
@@ -96,7 +137,8 @@ module YARD
|
|
96
137
|
@current_block = nil
|
97
138
|
process_block_token(tk) unless tk.class == TkSEMICOLON
|
98
139
|
@state = :block
|
99
|
-
when :block
|
140
|
+
when :block
|
141
|
+
process_block_token(tk)
|
100
142
|
when :post_block
|
101
143
|
if tk.class == TkSPACE
|
102
144
|
@statement << tk
|
@@ -113,9 +155,18 @@ module YARD
|
|
113
155
|
#
|
114
156
|
# @param [RubyToken::Token] tk the token to process
|
115
157
|
def process_block_token(tk)
|
116
|
-
|
117
|
-
|
118
|
-
|
158
|
+
if balances?(tk)
|
159
|
+
@statement << tk
|
160
|
+
@state = :first_statement
|
161
|
+
process_statement_end(tk)
|
162
|
+
elsif @block_num > 1 || (@block.empty? && [TkSPACE, TkNL].include?(tk.class))
|
163
|
+
@statement << tk
|
164
|
+
else
|
165
|
+
if @block.empty?
|
166
|
+
@statement << TkBlockContents.new(tk.line_no, tk.char_no)
|
167
|
+
end
|
168
|
+
@block << tk
|
169
|
+
end
|
119
170
|
end
|
120
171
|
|
121
172
|
##
|
@@ -132,6 +183,8 @@ module YARD
|
|
132
183
|
@comments = nil
|
133
184
|
return
|
134
185
|
end
|
186
|
+
|
187
|
+
@comments_line = tk.line_no unless @comments
|
135
188
|
|
136
189
|
# Remove the "#" and up to 1 space before the text
|
137
190
|
# Since, of course, the convention is to have "# text"
|
@@ -153,10 +206,17 @@ module YARD
|
|
153
206
|
# Make sure hashes are parsed as hashes, not as blocks
|
154
207
|
(@last_ns_tk.nil? || @last_ns_tk.lex_state != EXPR_BEG)
|
155
208
|
|
156
|
-
@block = TokenList.new
|
157
|
-
@block << tk
|
158
209
|
@level += 1
|
159
210
|
@state = :block
|
211
|
+
@block_num += 1
|
212
|
+
unless @block
|
213
|
+
@block = TokenList.new
|
214
|
+
tokens = [tk, TkStatementEnd.new(tk.line_no, tk.char_no)]
|
215
|
+
tokens = tokens.reverse if TkBEGIN === tk.class
|
216
|
+
@statement.push(*tokens)
|
217
|
+
else
|
218
|
+
@statement << tk
|
219
|
+
end
|
160
220
|
|
161
221
|
true
|
162
222
|
end
|
@@ -210,16 +270,25 @@ module YARD
|
|
210
270
|
|
211
271
|
# Continue with the statement if we've hit a comma in a def
|
212
272
|
return if @current_block == TkDEF && peek_no_space.class == TkCOMMA
|
213
|
-
|
273
|
+
|
274
|
+
|
275
|
+
if [TkEND_OF_SCRIPT, TkNL, TkSEMICOLON].include?(tk.class) && @state == :block_statement &&
|
276
|
+
[TkRBRACE, TkEND].include?(@last_ns_tk.class) && @level == 0
|
277
|
+
@current_block = nil
|
278
|
+
end
|
279
|
+
|
214
280
|
unless @current_block
|
215
281
|
@done = true
|
216
282
|
return
|
217
283
|
end
|
218
284
|
|
285
|
+
@state = :pre_block
|
219
286
|
@level += 1
|
220
|
-
@
|
221
|
-
@block
|
222
|
-
|
287
|
+
@block_num += 1
|
288
|
+
unless @block
|
289
|
+
@block = TokenList.new
|
290
|
+
@statement << TkStatementEnd.new(tk.line_no, tk.char_no)
|
291
|
+
end
|
223
292
|
end
|
224
293
|
|
225
294
|
##
|
@@ -236,7 +305,7 @@ module YARD
|
|
236
305
|
elsif [TkRPAREN, TkRBRACK, TkRBRACE, TkEND].include?(tk.class) && @level > 0
|
237
306
|
@level -= 1
|
238
307
|
end
|
239
|
-
|
308
|
+
|
240
309
|
@level == 0
|
241
310
|
end
|
242
311
|
|
@@ -246,7 +315,7 @@ module YARD
|
|
246
315
|
#
|
247
316
|
# @param [RubyToken::Token] tk the token to process
|
248
317
|
def push_token(tk)
|
249
|
-
@statement << tk unless @level == 0 && [
|
318
|
+
@statement << tk unless @level == 0 && [TkCOMMENT].include?(tk.class)
|
250
319
|
end
|
251
320
|
|
252
321
|
##
|
@@ -7,8 +7,16 @@ module YARD
|
|
7
7
|
self << content if content
|
8
8
|
end
|
9
9
|
|
10
|
-
def to_s
|
11
|
-
|
10
|
+
def to_s(full_statement = false, show_block = true)
|
11
|
+
inject([]) do |acc, token|
|
12
|
+
break acc if !full_statement && TkStatementEnd === token
|
13
|
+
if !show_block && TkBlockContents === token
|
14
|
+
acc << ""
|
15
|
+
else
|
16
|
+
acc << token.text
|
17
|
+
end
|
18
|
+
acc
|
19
|
+
end.join
|
12
20
|
end
|
13
21
|
|
14
22
|
# @param [TokenList, Token, String] tokens
|
@@ -17,11 +17,7 @@ module YARD
|
|
17
17
|
|
18
18
|
def parse(paths = "lib/**/*.rb", level = log.level)
|
19
19
|
log.debug("Parsing #{paths} with `#{parser_type}` parser")
|
20
|
-
|
21
|
-
files = paths.map {|p| Dir[p] }.flatten
|
22
|
-
else
|
23
|
-
files = Dir[File.join(Dir.pwd, paths)]
|
24
|
-
end
|
20
|
+
files = [paths].flatten.map {|p| p.include?("*") ? Dir[p] : p }.flatten
|
25
21
|
|
26
22
|
log.enter_level(level) do
|
27
23
|
parse_in_order(*files.uniq)
|
data/lib/yard/tags/library.rb
CHANGED
@@ -135,7 +135,7 @@ module YARD
|
|
135
135
|
define_tag "Deprecated", :deprecated
|
136
136
|
define_tag "Author", :author
|
137
137
|
define_tag "Raises", :raise, :with_types
|
138
|
-
define_tag "See Also", :see
|
138
|
+
define_tag "See Also", :see, :with_name
|
139
139
|
define_tag "Since", :since
|
140
140
|
define_tag "Version", :version
|
141
141
|
define_tag "API Visibility", :api
|
data/spec/cli/yardoc_spec.rb
CHANGED
@@ -9,6 +9,11 @@ describe YARD::CLI::Yardoc do
|
|
9
9
|
Registry.instance.stub!(:load)
|
10
10
|
end
|
11
11
|
|
12
|
+
it "should accept --title" do
|
13
|
+
@yardoc.optparse('--title', 'hello world')
|
14
|
+
@yardoc.options[:title].should == :'hello world'
|
15
|
+
end
|
16
|
+
|
12
17
|
it "should select a markup provider when --markup-provider or -mp is set" do
|
13
18
|
@yardoc.optparse("-M", "test")
|
14
19
|
@yardoc.options[:markup_provider].should == :test
|
@@ -40,4 +45,32 @@ describe YARD::CLI::Yardoc do
|
|
40
45
|
@yardoc.options[:serializer].options[:basepath].should == :MYPATH
|
41
46
|
@yardoc.files.should == ["FILE1", "FILE2", "FILE3"]
|
42
47
|
end
|
48
|
+
|
49
|
+
it "should accept extra files if specified after '-' with source files" do
|
50
|
+
File.should_receive(:file?).with('extra_file1').and_return(true)
|
51
|
+
File.should_receive(:file?).with('extra_file2').and_return(true)
|
52
|
+
@yardoc.optparse *%w( file1 file2 - extra_file1 extra_file2 )
|
53
|
+
@yardoc.files.should == %w( file1 file2 )
|
54
|
+
@yardoc.options[:files].should == %w( extra_file1 extra_file2 )
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should accept files section only containing extra files" do
|
58
|
+
@yardoc.optparse *%w( - LICENSE )
|
59
|
+
@yardoc.files.should == %w( lib/**/*.rb )
|
60
|
+
@yardoc.options[:files].should == %w( LICENSE )
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should accept globs as extra files" do
|
64
|
+
Dir.should_receive(:glob).with('*.txt').and_return ['a.txt', 'b.txt']
|
65
|
+
File.should_receive(:file?).with('a.txt').and_return(true)
|
66
|
+
File.should_receive(:file?).with('b.txt').and_return(true)
|
67
|
+
@yardoc.optparse *%w( file1 file2 - *.txt )
|
68
|
+
@yardoc.files.should == %w( file1 file2 )
|
69
|
+
@yardoc.options[:files].should == %w( a.txt b.txt )
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should accept no params and parse lib/**/*.rb" do
|
73
|
+
@yardoc.optparse
|
74
|
+
@yardoc.files.should == %w( lib/**/*.rb )
|
75
|
+
end
|
43
76
|
end
|
data/spec/docstring_spec.rb
CHANGED
@@ -25,6 +25,10 @@ describe YARD::Docstring do
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
+
it "should handle docstrings with empty newlines" do
|
29
|
+
Docstring.new("\n\n").should == ""
|
30
|
+
end
|
31
|
+
|
28
32
|
it "should handle empty docstrings with #summary" do
|
29
33
|
o1 = Docstring.new
|
30
34
|
o1.summary.should == ""
|
@@ -60,6 +64,26 @@ describe YARD::Docstring do
|
|
60
64
|
eof
|
61
65
|
doc.summary.should == "Returns a list of tags specified by +name+ or all tags if +name+ is not specified."
|
62
66
|
end
|
67
|
+
|
68
|
+
it "should only parse tags with charset [A-Za-z_]" do
|
69
|
+
doc = Docstring.new
|
70
|
+
valid = %w( @testing @valid @is_a @is_A @__ )
|
71
|
+
invalid = %w( @ @return@ @param, @x.y @x-y )
|
72
|
+
|
73
|
+
log.enter_level(Logger::FATAL) do
|
74
|
+
{valid => 1, invalid => 0}.each do |tags, size|
|
75
|
+
tags.each do |tag|
|
76
|
+
class << doc
|
77
|
+
def create_tag(tag_name, *args)
|
78
|
+
add_tag Tags::Tag.new(tag_name, *args)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
doc.all = tag
|
82
|
+
doc.tags(tag[1..-1]).size.should == size
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
63
87
|
|
64
88
|
it "should parse reference tag into ref_tags" do
|
65
89
|
doc = Docstring.new("@return (see Foo#bar)")
|
@@ -1,130 +1,132 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
2
|
|
3
|
-
describe YARD::Generators::Helpers::HtmlHelper
|
3
|
+
describe YARD::Generators::Helpers::HtmlHelper do
|
4
4
|
include YARD::Generators::Helpers::HtmlHelper
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
|
6
|
+
describe '#h' do
|
7
|
+
it "should use #h to escape HTML" do
|
8
|
+
h('Usage: foo "bar" <baz>').should == "Usage: foo "bar" <baz>"
|
9
|
+
end
|
8
10
|
end
|
9
11
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
describe '#fix_typewriter' do
|
13
|
+
it "should use #fix_typewriter to convert +text+ to <tt>text</tt>" do
|
14
|
+
fix_typewriter("Some +typewriter text+.").should == "Some <tt>typewriter text</tt>."
|
15
|
+
fix_typewriter("Not +typewriter text.").should == "Not +typewriter text."
|
16
|
+
fix_typewriter("Alternating +type writer+ text +here+.").should == "Alternating <tt>type writer</tt> text <tt>here</tt>."
|
17
|
+
fix_typewriter("No ++problem.").should == "No ++problem."
|
18
|
+
fix_typewriter("Math + stuff +is ok+").should == "Math + stuff <tt>is ok</tt>"
|
19
|
+
end
|
16
20
|
end
|
17
|
-
end
|
18
|
-
|
19
|
-
describe YARD::Generators::Helpers::HtmlHelper, "#link_object" do
|
20
|
-
include YARD::Generators::Helpers::HtmlHelper
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
describe '#htmlify' do
|
23
|
+
it "should not use hard breaks for textile markup (RedCloth specific)" do
|
24
|
+
htmlify("A\nB", :textile).should_not include("<br")
|
25
|
+
end
|
25
26
|
end
|
27
|
+
|
28
|
+
describe "#link_object" do
|
29
|
+
it "should return the object path if there's no serializer and no title" do
|
30
|
+
stub!(:serializer).and_return nil
|
31
|
+
link_object(CodeObjects::NamespaceObject.new(nil, :YARD)).should == "YARD"
|
32
|
+
end
|
26
33
|
|
27
|
-
|
28
|
-
|
29
|
-
|
34
|
+
it "should return the title if there's a title but no serializer" do
|
35
|
+
stub!(:serializer).and_return nil
|
36
|
+
link_object(CodeObjects::NamespaceObject.new(nil, :YARD), 'title').should == "title"
|
37
|
+
end
|
30
38
|
end
|
31
|
-
end
|
32
39
|
|
33
|
-
describe
|
34
|
-
|
35
|
-
|
36
|
-
before { Registry.clear }
|
40
|
+
describe '#url_for' do
|
41
|
+
before { Registry.clear }
|
37
42
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
+
it "should return nil if serializer is nil" do
|
44
|
+
stub!(:serializer).and_return nil
|
45
|
+
stub!(:current_object).and_return Registry.root
|
46
|
+
url_for(P("Mod::Class#meth")).should be_nil
|
47
|
+
end
|
43
48
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
+
it "should return nil if serializer does not implement #serialized_path" do
|
50
|
+
stub!(:serializer).and_return Serializers::Base.new
|
51
|
+
stub!(:current_object).and_return Registry.root
|
52
|
+
url_for(P("Mod::Class#meth")).should be_nil
|
53
|
+
end
|
49
54
|
|
50
|
-
|
51
|
-
|
52
|
-
|
55
|
+
it "should link to a path/file for a namespace object" do
|
56
|
+
stub!(:serializer).and_return Serializers::FileSystemSerializer.new
|
57
|
+
stub!(:current_object).and_return Registry.root
|
53
58
|
|
54
|
-
|
55
|
-
|
56
|
-
|
59
|
+
yard = CodeObjects::ModuleObject.new(:root, :YARD)
|
60
|
+
url_for(yard).should == 'YARD.html'
|
61
|
+
end
|
57
62
|
|
58
|
-
|
59
|
-
|
60
|
-
|
63
|
+
it "should link to the object's namespace path/file and use the object as the anchor" do
|
64
|
+
stub!(:serializer).and_return Serializers::FileSystemSerializer.new
|
65
|
+
stub!(:current_object).and_return Registry.root
|
61
66
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
67
|
+
yard = CodeObjects::ModuleObject.new(:root, :YARD)
|
68
|
+
meth = CodeObjects::MethodObject.new(yard, :meth)
|
69
|
+
url_for(meth).should == 'YARD.html#meth-instance_method'
|
70
|
+
end
|
66
71
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
72
|
+
it "should properly urlencode methods with punctuation in links" do
|
73
|
+
obj = CodeObjects::MethodObject.new(nil, :/)
|
74
|
+
serializer = mock(:serializer)
|
75
|
+
serializer.stub!(:serialized_path).and_return("file.html")
|
76
|
+
stub!(:serializer).and_return(serializer)
|
77
|
+
stub!(:current_object).and_return(obj)
|
78
|
+
url_for(obj).should == "#%2F-instance_method"
|
79
|
+
end
|
74
80
|
end
|
75
|
-
end
|
76
81
|
|
77
|
-
describe
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
anchor_for(obj).should == "/-instance_method"
|
82
|
+
describe '#anchor_for' do
|
83
|
+
it "should not urlencode data when called directly" do
|
84
|
+
obj = CodeObjects::MethodObject.new(nil, :/)
|
85
|
+
anchor_for(obj).should == "/-instance_method"
|
86
|
+
end
|
83
87
|
end
|
84
|
-
end
|
85
88
|
|
86
|
-
describe
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
results
|
89
|
+
describe '#resolve_links' do
|
90
|
+
def parse_link(link)
|
91
|
+
results = {}
|
92
|
+
link =~ /<a (.+?)>(.+?)<\/a>/
|
93
|
+
params, results[:inner_text] = $1, $2
|
94
|
+
params.split(/\s+/).each do |match|
|
95
|
+
key, value = *match.split('=')
|
96
|
+
results[key.to_sym] = value.gsub(/^["'](.+)["']$/, '\1')
|
97
|
+
end
|
98
|
+
results
|
96
99
|
end
|
97
|
-
results
|
98
|
-
end
|
99
100
|
|
100
|
-
|
101
|
-
|
102
|
-
|
101
|
+
it "should link static files with file: prefix" do
|
102
|
+
stub!(:serializer).and_return Serializers::FileSystemSerializer.new
|
103
|
+
stub!(:current_object).and_return Registry.root
|
103
104
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
105
|
+
parse_link(resolve_links("{file:TEST.txt#abc}")).should == {
|
106
|
+
:inner_text => "TEST.txt",
|
107
|
+
:title => "TEST.txt",
|
108
|
+
:href => "TEST.txt.html#abc"
|
109
|
+
}
|
110
|
+
parse_link(resolve_links("{file:TEST.txt title}")).should == {
|
111
|
+
:inner_text => "title",
|
112
|
+
:title => "title",
|
113
|
+
:href => "TEST.txt.html"
|
114
|
+
}
|
115
|
+
end
|
115
116
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
117
|
+
it "should create regular links with http:// or https:// prefixes" do
|
118
|
+
parse_link(resolve_links("{http://example.com}")).should == {
|
119
|
+
:inner_text => "http://example.com",
|
120
|
+
:target => "_parent",
|
121
|
+
:href => "http://example.com",
|
122
|
+
:title => "http://example.com"
|
123
|
+
}
|
124
|
+
parse_link(resolve_links("{http://example.com title}")).should == {
|
125
|
+
:inner_text => "title",
|
126
|
+
:target => "_parent",
|
127
|
+
:href => "http://example.com",
|
128
|
+
:title => "title"
|
129
|
+
}
|
130
|
+
end
|
129
131
|
end
|
130
132
|
end
|