yard 0.8.0 → 0.8.1
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/ChangeLog +67 -1
- data/README.md +8 -2
- data/docs/WhatsNew.md +34 -0
- data/lib/yard.rb +1 -1
- data/lib/yard/autoload.rb +2 -0
- data/lib/yard/cli/list.rb +1 -1
- data/lib/yard/cli/stats.rb +5 -1
- data/lib/yard/cli/yardoc.rb +27 -1
- data/lib/yard/code_objects/macro_object.rb +1 -1
- data/lib/yard/docstring.rb +28 -2
- data/lib/yard/docstring_parser.rb +69 -40
- data/lib/yard/handlers/base.rb +1 -1
- data/lib/yard/i18n/message.rb +56 -0
- data/lib/yard/i18n/messages.rb +55 -0
- data/lib/yard/i18n/pot_generator.rb +49 -50
- data/lib/yard/tags/directives.rb +1 -1
- data/lib/yard/tags/library.rb +42 -15
- data/lib/yard/verifier.rb +2 -2
- data/spec/cli/list_spec.rb +1 -1
- data/spec/cli/stats_spec.rb +5 -5
- data/spec/cli/yardoc_spec.rb +71 -2
- data/spec/docstring_parser_spec.rb +17 -0
- data/spec/i18n/message_spec.rb +52 -0
- data/spec/i18n/messages_spec.rb +67 -0
- data/spec/i18n/pot_generator_spec.rb +45 -27
- data/spec/i18n/text_spec.rb +2 -0
- data/spec/verifier_spec.rb +20 -0
- data/templates/default/fulldoc/html/{full_list_methods.erb → full_list_method.erb} +0 -0
- data/templates/default/fulldoc/html/setup.rb +1 -1
- data/templates/default/tags/html/option.erb +3 -1
- metadata +7 -3
data/spec/cli/list_spec.rb
CHANGED
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/../spec_helper'
|
|
2
2
|
|
3
3
|
describe YARD::CLI::List do
|
4
4
|
it "should pass command off to Yardoc with --list" do
|
5
|
-
YARD::CLI::Yardoc.should_receive(:run).with('--list', '--foo')
|
5
|
+
YARD::CLI::Yardoc.should_receive(:run).with('-c', '--list', '--foo')
|
6
6
|
YARD::CLI::List.run('--foo')
|
7
7
|
end
|
8
8
|
end
|
data/spec/cli/stats_spec.rb
CHANGED
@@ -77,13 +77,13 @@ eof
|
|
77
77
|
@output.string.should == @main_stats
|
78
78
|
end
|
79
79
|
|
80
|
-
it "should
|
80
|
+
it "should ignore everything with --no-public" do
|
81
81
|
@stats.run('--no-public')
|
82
82
|
@output.string.should ==
|
83
|
-
"Files:
|
84
|
-
"Modules:
|
85
|
-
"Classes:
|
86
|
-
"Constants:
|
83
|
+
"Files: 0\n" +
|
84
|
+
"Modules: 0 ( 0 undocumented)\n" +
|
85
|
+
"Classes: 0 ( 0 undocumented)\n" +
|
86
|
+
"Constants: 0 ( 0 undocumented)\n" +
|
87
87
|
"Methods: 0 ( 0 undocumented)\n" +
|
88
88
|
" 0.00% documented\n"
|
89
89
|
end
|
data/spec/cli/yardoc_spec.rb
CHANGED
@@ -305,6 +305,71 @@ describe YARD::CLI::Yardoc do
|
|
305
305
|
end
|
306
306
|
end
|
307
307
|
|
308
|
+
describe '--[no-]api' do
|
309
|
+
before { Registry.clear }
|
310
|
+
|
311
|
+
it "should allow --api name" do
|
312
|
+
YARD.parse_string <<-eof
|
313
|
+
# @api private
|
314
|
+
class Foo; end
|
315
|
+
# @api public
|
316
|
+
class Bar; end
|
317
|
+
class Baz; end
|
318
|
+
eof
|
319
|
+
@yardoc.run('--api', 'private')
|
320
|
+
@yardoc.options.verifier.run(Registry.all).should == [P('Foo')]
|
321
|
+
end
|
322
|
+
|
323
|
+
it "should allow multiple --api's to all be shown" do
|
324
|
+
YARD.parse_string <<-eof
|
325
|
+
# @api private
|
326
|
+
class Foo; end
|
327
|
+
# @api public
|
328
|
+
class Bar; end
|
329
|
+
class Baz; end
|
330
|
+
eof
|
331
|
+
@yardoc.run('--api', 'private', '--api', 'public')
|
332
|
+
@yardoc.options.verifier.run(Registry.all).
|
333
|
+
sort_by {|o| o.path }.should == [P('Bar'), P('Foo')]
|
334
|
+
end
|
335
|
+
|
336
|
+
it "should allow --no-api to specify objects with no @api tag" do
|
337
|
+
YARD.parse_string <<-eof
|
338
|
+
# @api private
|
339
|
+
class Foo; end
|
340
|
+
# @api public
|
341
|
+
class Bar; end
|
342
|
+
class Baz; end
|
343
|
+
eof
|
344
|
+
@yardoc.run('--api', '')
|
345
|
+
@yardoc.options.verifier.run(Registry.all).should == [P('Baz')]
|
346
|
+
@yardoc.options.verifier = Verifier.new
|
347
|
+
@yardoc.run('--no-api')
|
348
|
+
@yardoc.options.verifier.run(Registry.all).should == [P('Baz')]
|
349
|
+
end
|
350
|
+
|
351
|
+
it "should allow --no-api to work with other --api switches" do
|
352
|
+
YARD.parse_string <<-eof
|
353
|
+
# @api private
|
354
|
+
class Foo; end
|
355
|
+
# @api public
|
356
|
+
class Bar; end
|
357
|
+
class Baz; end
|
358
|
+
eof
|
359
|
+
@yardoc.run('--no-api', '--api', 'public')
|
360
|
+
@yardoc.options.verifier.run(Registry.all).
|
361
|
+
sort_by {|o| o.path }.should == [P('Bar'), P('Baz')]
|
362
|
+
end
|
363
|
+
|
364
|
+
it "should ensure Ruby code cannot be used" do
|
365
|
+
[':symbol', '42', '"; exit'].each do |ruby|
|
366
|
+
@yardoc.options.verifier.expressions = []
|
367
|
+
@yardoc.run('--api', ruby)
|
368
|
+
@yardoc.options.verifier.expressions[1].should include(ruby.inspect)
|
369
|
+
end
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
308
373
|
describe '--no-private option' do
|
309
374
|
it "should accept --no-private" do
|
310
375
|
obj = mock(:object)
|
@@ -406,8 +471,12 @@ describe YARD::CLI::Yardoc do
|
|
406
471
|
end
|
407
472
|
|
408
473
|
describe 'Query options' do
|
409
|
-
|
410
|
-
|
474
|
+
after { Registry.clear }
|
475
|
+
|
476
|
+
it "should hide private constants in with default visibilities" do
|
477
|
+
classobj = CodeObjects::ClassObject.new(:root, :Foo) {|o| o.visibility = :private }
|
478
|
+
@yardoc.run
|
479
|
+
@yardoc.options.verifier.run([classobj]).should == []
|
411
480
|
end
|
412
481
|
|
413
482
|
it "should setup visibility rules as verifier" do
|
@@ -203,5 +203,22 @@ eof
|
|
203
203
|
parser.parse("Some text")
|
204
204
|
the_yielded_obj.should == parser
|
205
205
|
end
|
206
|
+
|
207
|
+
it "should warn about invalid named parameters" do
|
208
|
+
log.should_receive(:warn).with(/@param tag has unknown parameter name: notaparam/)
|
209
|
+
YARD.parse_string <<-eof
|
210
|
+
# @param notaparam foo
|
211
|
+
def foo(a) end
|
212
|
+
eof
|
213
|
+
end
|
214
|
+
|
215
|
+
it "should warn about duplicate named parameters" do
|
216
|
+
log.should_receive(:warn).with(/@param tag has duplicate parameter name: a/)
|
217
|
+
YARD.parse_string <<-eof
|
218
|
+
# @param a foo
|
219
|
+
# @param a foo
|
220
|
+
def foo(a) end
|
221
|
+
eof
|
222
|
+
end
|
206
223
|
end
|
207
224
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe YARD::I18n::Message do
|
4
|
+
def message(id)
|
5
|
+
YARD::I18n::Message.new(id)
|
6
|
+
end
|
7
|
+
|
8
|
+
before do
|
9
|
+
@message = message("Hello World!")
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#id" do
|
13
|
+
it "should return ID" do
|
14
|
+
message("Hello World!").id.should == "Hello World!"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "#add_location" do
|
19
|
+
it "should add some locations" do
|
20
|
+
@message.add_location("hello.rb", 10)
|
21
|
+
@message.add_location("message.rb", 5)
|
22
|
+
@message.locations.should == Set.new([["hello.rb", 10], ["message.rb", 5]])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#add_comment" do
|
27
|
+
it "should add some comments" do
|
28
|
+
@message.add_comment("YARD.title")
|
29
|
+
@message.add_comment("Hello#message")
|
30
|
+
@message.comments.should == Set.new(["YARD.title", "Hello#message"])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#==" do
|
35
|
+
it "should return true for same value messages" do
|
36
|
+
locations = [["hello.rb", 10], ["message.rb", 5]]
|
37
|
+
comments = ["YARD.title", "Hello#message"]
|
38
|
+
|
39
|
+
other_message = message(@message.id)
|
40
|
+
locations.each do |path, line|
|
41
|
+
@message.add_location(path, line)
|
42
|
+
other_message.add_location(path, line)
|
43
|
+
end
|
44
|
+
comments.each do |comment|
|
45
|
+
@message.add_comment(comment)
|
46
|
+
other_message.add_comment(comment)
|
47
|
+
end
|
48
|
+
|
49
|
+
@message.should == other_message
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe YARD::I18n::Messages do
|
4
|
+
def message(id)
|
5
|
+
YARD::I18n::Message.new(id)
|
6
|
+
end
|
7
|
+
|
8
|
+
def messages
|
9
|
+
YARD::I18n::Messages.new
|
10
|
+
end
|
11
|
+
|
12
|
+
before do
|
13
|
+
@messages = messages
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#each" do
|
17
|
+
it "should enumerate Message" do
|
18
|
+
@messages.register("Hello World!")
|
19
|
+
@messages.register("Title")
|
20
|
+
enumerated_messages = []
|
21
|
+
@messages.each do |message|
|
22
|
+
enumerated_messages << message
|
23
|
+
end
|
24
|
+
enumerated_messages = enumerated_messages.sort_by {|m| m.id }
|
25
|
+
enumerated_messages.should == [message("Hello World!"), message("Title")]
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should not any Message for empty messages" do
|
29
|
+
enumerated_messages = []
|
30
|
+
@messages.each do |message|
|
31
|
+
enumerated_messages << message
|
32
|
+
end
|
33
|
+
enumerated_messages.should == []
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#[]" do
|
38
|
+
it "should return registered message" do
|
39
|
+
@messages.register("Hello World!")
|
40
|
+
@messages["Hello World!"].should == message("Hello World!")
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should return for nonexistent message ID" do
|
44
|
+
@messages["Hello World!"].should == nil
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "#register" do
|
49
|
+
it "should return registered message" do
|
50
|
+
@messages.register("Hello World!").should == message("Hello World!")
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should return existent message" do
|
54
|
+
message = @messages.register("Hello World!")
|
55
|
+
@messages.register("Hello World!").object_id.should == message.object_id
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "#==" do
|
60
|
+
it "should return true for same value messages" do
|
61
|
+
@messages.register("Hello World!")
|
62
|
+
other_messages = messages
|
63
|
+
other_messages.register("Hello World!")
|
64
|
+
@messages.should == other_messages
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -1,6 +1,24 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../spec_helper'
|
2
2
|
|
3
3
|
describe YARD::I18n::PotGenerator do
|
4
|
+
def create_messages(messages)
|
5
|
+
yard_messages = YARD::I18n::Messages.new
|
6
|
+
add_messages(yard_messages, messages)
|
7
|
+
yard_messages
|
8
|
+
end
|
9
|
+
|
10
|
+
def add_messages(yard_messages, messages)
|
11
|
+
messages.each do |id, properties|
|
12
|
+
yard_message = yard_messages.register(id)
|
13
|
+
(properties[:locations] || []).each do |path, line|
|
14
|
+
yard_message.add_location(path, line)
|
15
|
+
end
|
16
|
+
(properties[:comments] || []).each do |comment|
|
17
|
+
yard_message.add_comment(comment)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
4
22
|
before do
|
5
23
|
@generator = YARD::I18n::PotGenerator.new("..")
|
6
24
|
end
|
@@ -32,14 +50,17 @@ eoh
|
|
32
50
|
|
33
51
|
it "should generate messages in location order" do
|
34
52
|
@generator.stub!(:header).and_return("HEADER\n\n")
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
53
|
+
messages = {
|
54
|
+
"tag|see|Parser::SourceParser.parse" => {
|
55
|
+
:locations => [["yard.rb", 14]],
|
56
|
+
:comments => ["@see"],
|
57
|
+
},
|
58
|
+
"Parses a path or set of paths" => {
|
59
|
+
:locations => [["yard.rb", 12], ["yard/parser/source_parser.rb", 83]],
|
60
|
+
:comments => ["YARD.parse", "YARD::Parser::SourceParser.parse"],
|
61
|
+
}
|
42
62
|
}
|
63
|
+
add_messages(@generator.messages, messages)
|
43
64
|
@generator.generate.should == <<-'eoh'
|
44
65
|
HEADER
|
45
66
|
|
@@ -60,13 +81,10 @@ eoh
|
|
60
81
|
end
|
61
82
|
|
62
83
|
describe "Escape" do
|
63
|
-
def generate_message_pot(
|
84
|
+
def generate_message_pot(message_id)
|
64
85
|
pot = ""
|
65
|
-
|
66
|
-
|
67
|
-
:locations => [],
|
68
|
-
}
|
69
|
-
@generator.send(:generate_message, pot, message, options)
|
86
|
+
message = YARD::I18n::Message.new(message_id)
|
87
|
+
@generator.send(:generate_message, pot, message)
|
70
88
|
pot
|
71
89
|
end
|
72
90
|
|
@@ -107,12 +125,12 @@ eop
|
|
107
125
|
o.docstring = "An alias to {Parser::SourceParser}'s parsing method"
|
108
126
|
end
|
109
127
|
@generator.parse_objects([object])
|
110
|
-
@generator.messages.should == {
|
128
|
+
@generator.messages.should == create_messages({
|
111
129
|
"An alias to {Parser::SourceParser}'s parsing method" => {
|
112
130
|
:locations => [],
|
113
131
|
:comments => ["YARD.parse"],
|
114
132
|
}
|
115
|
-
}
|
133
|
+
})
|
116
134
|
end
|
117
135
|
|
118
136
|
it "should extract location" do
|
@@ -121,12 +139,12 @@ eop
|
|
121
139
|
o.files = [["yard.rb", 12]]
|
122
140
|
end
|
123
141
|
@generator.parse_objects([object])
|
124
|
-
@generator.messages.should == {
|
142
|
+
@generator.messages.should == create_messages({
|
125
143
|
"An alias to {Parser::SourceParser}'s parsing method" => {
|
126
144
|
:locations => [["yard.rb", 13]],
|
127
145
|
:comments => ["YARD.parse"],
|
128
146
|
}
|
129
|
-
}
|
147
|
+
})
|
130
148
|
end
|
131
149
|
|
132
150
|
it "should extract tag name" do
|
@@ -135,12 +153,12 @@ eop
|
|
135
153
|
o.files = [["yard.rb", 12]]
|
136
154
|
end
|
137
155
|
@generator.parse_objects([object])
|
138
|
-
@generator.messages.should == {
|
156
|
+
@generator.messages.should == create_messages({
|
139
157
|
"tag|see|Parser::SourceParser.parse" => {
|
140
158
|
:locations => [["yard.rb", 12]],
|
141
159
|
:comments => ["@see"],
|
142
160
|
},
|
143
|
-
}
|
161
|
+
})
|
144
162
|
end
|
145
163
|
|
146
164
|
it "should extract tag text" do
|
@@ -152,7 +170,7 @@ eod
|
|
152
170
|
o.files = [["yard.rb", 12]]
|
153
171
|
end
|
154
172
|
@generator.parse_objects([object])
|
155
|
-
@generator.messages.should == {
|
173
|
+
@generator.messages.should == create_messages({
|
156
174
|
"tag|example|Parse a glob of files" => {
|
157
175
|
:locations => [["yard.rb", 12]],
|
158
176
|
:comments => ["@example"],
|
@@ -161,7 +179,7 @@ eod
|
|
161
179
|
:locations => [["yard.rb", 12]],
|
162
180
|
:comments => ["@example Parse a glob of files"],
|
163
181
|
}
|
164
|
-
}
|
182
|
+
})
|
165
183
|
end
|
166
184
|
|
167
185
|
it "should extract tag types" do
|
@@ -173,7 +191,7 @@ eod
|
|
173
191
|
o.files = [["yard.rb", 12]]
|
174
192
|
end
|
175
193
|
@generator.parse_objects([object])
|
176
|
-
@generator.messages.should == {
|
194
|
+
@generator.messages.should == create_messages({
|
177
195
|
"tag|param|paths" => {
|
178
196
|
:locations => [["yard.rb", 12]],
|
179
197
|
:comments => ["@param [String, Array<String>]"],
|
@@ -182,7 +200,7 @@ eod
|
|
182
200
|
:locations => [["yard.rb", 12]],
|
183
201
|
:comments => ["@param [String, Array<String>] paths"],
|
184
202
|
}
|
185
|
-
}
|
203
|
+
})
|
186
204
|
end
|
187
205
|
end
|
188
206
|
|
@@ -198,7 +216,7 @@ eor
|
|
198
216
|
File.stub!(:read).with(path).and_return(text)
|
199
217
|
file = YARD::CodeObjects::ExtraFileObject.new(path)
|
200
218
|
@generator.parse_files([file])
|
201
|
-
@generator.messages.should == {
|
219
|
+
@generator.messages.should == create_messages({
|
202
220
|
"Getting Started Guide" => {
|
203
221
|
:locations => [[path, 1]],
|
204
222
|
:comments => ["title"],
|
@@ -207,7 +225,7 @@ eor
|
|
207
225
|
:locations => [[path, 3]],
|
208
226
|
:comments => [],
|
209
227
|
}
|
210
|
-
}
|
228
|
+
})
|
211
229
|
end
|
212
230
|
|
213
231
|
it "should extract paragraphs" do
|
@@ -229,7 +247,7 @@ eot
|
|
229
247
|
File.stub!(:read).with(path).and_return(text)
|
230
248
|
file = YARD::CodeObjects::ExtraFileObject.new(path)
|
231
249
|
@generator.parse_files([file])
|
232
|
-
@generator.messages.should == {
|
250
|
+
@generator.messages.should == create_messages({
|
233
251
|
paragraph1 => {
|
234
252
|
:locations => [[path, 1]],
|
235
253
|
:comments => [],
|
@@ -238,7 +256,7 @@ eot
|
|
238
256
|
:locations => [[path, 4]],
|
239
257
|
:comments => [],
|
240
258
|
}
|
241
|
-
}
|
259
|
+
})
|
242
260
|
end
|
243
261
|
end
|
244
262
|
end
|
data/spec/i18n/text_spec.rb
CHANGED
data/spec/verifier_spec.rb
CHANGED
@@ -19,6 +19,26 @@ describe YARD::Verifier do
|
|
19
19
|
Verifier.new('@@return').call(obj)
|
20
20
|
end
|
21
21
|
|
22
|
+
it "should allow namespaced tag using @{} syntax" do
|
23
|
+
obj = mock(:object)
|
24
|
+
obj.should_receive(:tag).with('yard.return')
|
25
|
+
Verifier.new('@{yard.return}').call(obj)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should allow namespaced tags using @{} syntax" do
|
29
|
+
obj = mock(:object)
|
30
|
+
obj.should_receive(:tags).with('yard.return')
|
31
|
+
Verifier.new('@@{yard.return}').call(obj)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should call methods on tag object" do
|
35
|
+
obj = mock(:object)
|
36
|
+
obj2 = mock(:tag)
|
37
|
+
obj.should_receive(:tag).with('return').and_return obj2
|
38
|
+
obj2.should_receive(:foo)
|
39
|
+
Verifier.new('@return.foo').call(obj)
|
40
|
+
end
|
41
|
+
|
22
42
|
it "should send any missing methods to object" do
|
23
43
|
obj = mock(:object)
|
24
44
|
obj.should_receive(:has_tag?).with('return')
|