yard 0.8.1 → 0.8.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/ChangeLog +192 -0
- data/README.md +9 -2
- data/Rakefile +8 -14
- data/lib/yard.rb +1 -1
- data/lib/yard/autoload.rb +3 -2
- data/lib/yard/cli/graph.rb +28 -10
- data/lib/yard/cli/yardoc.rb +4 -1
- data/lib/yard/code_objects/proxy.rb +22 -17
- data/lib/yard/docstring_parser.rb +7 -7
- data/lib/yard/globals.rb +2 -2
- data/lib/yard/handlers/base.rb +3 -2
- data/lib/yard/handlers/c/handler_methods.rb +1 -0
- data/lib/yard/handlers/c/init_handler.rb +7 -5
- data/lib/yard/handlers/c/override_comment_handler.rb +9 -1
- data/lib/yard/handlers/ruby/class_condition_handler.rb +4 -2
- data/lib/yard/handlers/ruby/legacy/class_condition_handler.rb +4 -2
- data/lib/yard/handlers/ruby/legacy/mixin_handler.rb +4 -6
- data/lib/yard/handlers/ruby/mixin_handler.rb +3 -3
- data/lib/yard/handlers/ruby/visibility_handler.rb +1 -1
- data/lib/yard/i18n/locale.rb +50 -0
- data/lib/yard/i18n/text.rb +110 -9
- data/lib/yard/logging.rb +99 -8
- data/lib/yard/parser/c/c_parser.rb +1 -1
- data/lib/yard/parser/source_parser.rb +5 -4
- data/lib/yard/registry.rb +20 -12
- data/lib/yard/registry_store.rb +6 -1
- data/lib/yard/rubygems/doc_manager.rb +9 -5
- data/lib/yard/serializers/yardoc_serializer.rb +1 -0
- data/lib/yard/server/commands/base.rb +3 -2
- data/lib/yard/server/doc_server_serializer.rb +2 -0
- data/lib/yard/server/templates/default/method_details/html/permalink.erb +4 -0
- data/lib/yard/server/templates/default/method_details/html/setup.rb +4 -0
- data/lib/yard/tags/default_factory.rb +12 -4
- data/lib/yard/tags/directives.rb +1 -0
- data/lib/yard/templates/engine.rb +13 -6
- data/lib/yard/templates/template_options.rb +8 -1
- data/spec/cli/graph_spec.rb +10 -0
- data/spec/cli/yri_spec.rb +12 -2
- data/spec/code_objects/proxy_spec.rb +19 -3
- data/spec/handlers/c/class_handler_spec.rb +1 -2
- data/spec/handlers/c/init_handler_spec.rb +11 -0
- data/spec/handlers/c/override_comment_handler_spec.rb +3 -0
- data/spec/handlers/class_condition_handler_spec.rb +5 -0
- data/spec/handlers/dsl_handler_spec.rb +1 -0
- data/spec/handlers/examples/class_condition_handler_001.rb.txt +8 -0
- data/spec/handlers/mixin_handler_spec.rb +2 -1
- data/spec/i18n/locale_spec.rb +62 -0
- data/spec/i18n/text_spec.rb +144 -35
- data/spec/logging_spec.rb +21 -0
- data/spec/parser/c_parser_spec.rb +36 -0
- data/spec/parser/source_parser_spec.rb +11 -8
- data/spec/registry_spec.rb +26 -0
- data/spec/rubygems/doc_manager_spec.rb +112 -0
- data/spec/tags/default_factory_spec.rb +8 -2
- data/spec/tags/directives_spec.rb +7 -0
- data/spec/templates/examples/module001.html +0 -4
- data/spec/templates/examples/module002.html +0 -1
- data/spec/templates/examples/module003.html +0 -1
- data/spec/templates/examples/module004.html +171 -172
- data/spec/templates/module_spec.rb +4 -0
- data/templates/default/fulldoc/html/js/app.js +24 -18
- data/templates/default/fulldoc/html/setup.rb +5 -1
- data/templates/default/module/html/attribute_details.erb +1 -2
- metadata +9 -4
- data/lib/yard/server/templates/default/fulldoc/html/js/live.js +0 -17
@@ -4,6 +4,7 @@ describe YARD::Handlers::C::OverrideCommentHandler do
|
|
4
4
|
[:class, :module].each do |type|
|
5
5
|
it "should handle Document-#{type}" do
|
6
6
|
parse(<<-eof)
|
7
|
+
void something;
|
7
8
|
/* Document-#{type}: A
|
8
9
|
* Foo bar baz
|
9
10
|
*/
|
@@ -11,6 +12,8 @@ describe YARD::Handlers::C::OverrideCommentHandler do
|
|
11
12
|
eof
|
12
13
|
Registry.at('A').type.should == type
|
13
14
|
Registry.at('A').docstring.should == 'Foo bar baz'
|
15
|
+
Registry.at('A').file.should == '(stdin)'
|
16
|
+
Registry.at('A').line.should == 2
|
14
17
|
end
|
15
18
|
end
|
16
19
|
|
@@ -48,6 +48,11 @@ describe "YARD::Handlers::Ruby::#{LEGACY_PARSER ? "Legacy::" : ""}ClassCondition
|
|
48
48
|
verify_method :n
|
49
49
|
end
|
50
50
|
|
51
|
+
it "should maintain visibility and scope state inside condition" do
|
52
|
+
Registry.at('A#m').visibility.should == :private
|
53
|
+
Registry.at('A#mnot').visibility.should == :private
|
54
|
+
end
|
55
|
+
|
51
56
|
it "should not fail on complex conditions" do
|
52
57
|
log.should_not_receive(:warn)
|
53
58
|
log.should_not_receive(:error)
|
@@ -61,6 +61,7 @@ describe "YARD::Handlers::Ruby::#{LEGACY_PARSER ? "Legacy::" : ""}DSLHandler" do
|
|
61
61
|
obj = Registry.at('Foo.xyz')
|
62
62
|
obj.should_not be_nil
|
63
63
|
obj.signature.should == 'def xyz(a, b, c)'
|
64
|
+
obj.parameters.should == [[:a, nil], [:b, nil], [:c, nil]]
|
64
65
|
obj.source.should == 'foo_bar'
|
65
66
|
obj.docstring.should == 'The foo method'
|
66
67
|
end
|
@@ -17,7 +17,8 @@ describe "YARD::Handlers::Ruby::#{LEGACY_PARSER ? "Legacy::" : ""}MixinHandler"
|
|
17
17
|
end
|
18
18
|
|
19
19
|
it "should set the type of non-existing modules to :module" do
|
20
|
-
|
20
|
+
o = Registry.at(:X).instance_mixins.find {|o| o.name == :NOTEXIST }
|
21
|
+
o.type.should == :module
|
21
22
|
end
|
22
23
|
|
23
24
|
it "should handle includes with multiple parameters" do
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe YARD::I18n::Locale do
|
4
|
+
def locale(name)
|
5
|
+
YARD::I18n::Locale.new(name)
|
6
|
+
end
|
7
|
+
|
8
|
+
before do
|
9
|
+
@locale = locale("fr")
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#name" do
|
13
|
+
it "should return name" do
|
14
|
+
locale("fr").name.should == "fr"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "#load" do
|
19
|
+
it "should return false for nonexistent PO" do
|
20
|
+
File.should_receive(:exist?).with('foo/fr.po').and_return(false)
|
21
|
+
@locale.load('foo').should == false
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should return true for existent PO" do
|
25
|
+
data = <<-eop
|
26
|
+
msgid ""
|
27
|
+
msgstr ""
|
28
|
+
"Language: fr\n"
|
29
|
+
"MIME-Version: 1.0\n"
|
30
|
+
"Content-Type: text/plain; charset=UTF-8\n"
|
31
|
+
"Content-Transfer-Encoding: 8bit\n"
|
32
|
+
|
33
|
+
msgid "Hello"
|
34
|
+
msgstr "Bonjour"
|
35
|
+
eop
|
36
|
+
parser = GetText::PoParser.new
|
37
|
+
File.should_receive(:exist?).with('foo/fr.po').and_return(true)
|
38
|
+
GetText::PoParser.should_receive(:new).and_return(parser)
|
39
|
+
parser.should_receive(:parse_file) do |file, hash|
|
40
|
+
file.should == 'foo/fr.po'
|
41
|
+
parser.parse(data, hash)
|
42
|
+
end
|
43
|
+
@locale.load('foo').should == true
|
44
|
+
@locale.translate('Hello').should == "Bonjour"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "#translate" do
|
49
|
+
before do
|
50
|
+
messages = @locale.instance_variable_get(:@messages)
|
51
|
+
messages["Hello"] = "Bonjour"
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should return translated string for existent string" do
|
55
|
+
@locale.translate("Hello") == "Bonjour"
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should return original string for nonexistent string" do
|
59
|
+
@locale.translate("nonexistent") == "nonexistent"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/spec/i18n/text_spec.rb
CHANGED
@@ -1,71 +1,180 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../spec_helper'
|
2
2
|
|
3
3
|
describe YARD::I18n::Text do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
describe "#extract_messages" do
|
5
|
+
def extract_messages(input, options={})
|
6
|
+
text = YARD::I18n::Text.new(StringIO.new(input), options)
|
7
|
+
messages = []
|
8
|
+
text.extract_messages do |*message|
|
9
|
+
messages << message
|
10
|
+
end
|
11
|
+
messages
|
9
12
|
end
|
10
|
-
messages
|
11
|
-
end
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
14
|
+
describe "Header" do
|
15
|
+
it "should extract attribute" do
|
16
|
+
text = <<-eot
|
16
17
|
# @title Getting Started Guide
|
17
18
|
|
18
19
|
# Getting Started with YARD
|
19
20
|
eot
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
extract_messages(text, :have_header => true).should ==
|
22
|
+
[[:attribute, "title", "Getting Started Guide", 1],
|
23
|
+
[:paragraph, "# Getting Started with YARD", 3]]
|
24
|
+
end
|
24
25
|
|
25
|
-
|
26
|
-
|
26
|
+
it "should ignore markup line" do
|
27
|
+
text = <<-eot
|
27
28
|
#!markdown
|
28
29
|
# @title Getting Started Guide
|
29
30
|
|
30
31
|
# Getting Started with YARD
|
31
32
|
eot
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
extract_messages(text, :have_header => true).should ==
|
34
|
+
[[:attribute, "title", "Getting Started Guide", 2],
|
35
|
+
[:paragraph, "# Getting Started with YARD", 4]]
|
36
|
+
end
|
36
37
|
|
37
|
-
|
38
|
-
|
38
|
+
it "should terminate header block by markup line not at the first line" do
|
39
|
+
text = <<-eot
|
39
40
|
# @title Getting Started Guide
|
40
41
|
#!markdown
|
41
42
|
|
42
43
|
# Getting Started with YARD
|
43
44
|
eot
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
45
|
+
extract_messages(text, :have_header => true).should ==
|
46
|
+
[[:attribute, "title", "Getting Started Guide", 1],
|
47
|
+
[:paragraph, "#!markdown", 2],
|
48
|
+
[:paragraph, "# Getting Started with YARD", 4]]
|
49
|
+
end
|
48
50
|
end
|
49
|
-
end
|
50
51
|
|
51
|
-
|
52
|
-
|
53
|
-
|
52
|
+
describe "Body" do
|
53
|
+
it "should split to paragraphs" do
|
54
|
+
paragraph1 = <<-eop.strip
|
54
55
|
Note that class methods must not be referred to with the "::" namespace
|
55
56
|
separator. Only modules, classes and constants should use "::".
|
56
57
|
eop
|
57
|
-
|
58
|
+
paragraph2 = <<-eop.strip
|
58
59
|
You can also do lookups on any installed gems. Just make sure to build the
|
59
60
|
.yardoc databases for installed gems with:
|
60
61
|
eop
|
61
|
-
|
62
|
+
text = <<-eot
|
62
63
|
#{paragraph1}
|
63
64
|
|
64
65
|
#{paragraph2}
|
65
66
|
eot
|
66
|
-
|
67
|
-
|
68
|
-
|
67
|
+
extract_messages(text).should ==
|
68
|
+
[[:paragraph, paragraph1, 1],
|
69
|
+
[:paragraph, paragraph2, 4]]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "#translate" do
|
75
|
+
def locale
|
76
|
+
locale = YARD::I18n::Locale.new("fr")
|
77
|
+
messages = locale.instance_variable_get(:@messages)
|
78
|
+
messages["markdown"] = "markdown (markdown in fr)"
|
79
|
+
messages["Hello"] = "Bonjour (Hello in fr)"
|
80
|
+
messages["Paragraph 1."] = "Paragraphe 1."
|
81
|
+
messages["Paragraph 2."] = "Paragraphe 2."
|
82
|
+
locale
|
83
|
+
end
|
84
|
+
|
85
|
+
def translate(input, options={})
|
86
|
+
text = YARD::I18n::Text.new(StringIO.new(input), options)
|
87
|
+
text.translate(locale)
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "Header" do
|
91
|
+
it "should extract attribute" do
|
92
|
+
text = <<-eot
|
93
|
+
# @title Hello
|
94
|
+
|
95
|
+
# Getting Started with YARD
|
96
|
+
|
97
|
+
Paragraph.
|
98
|
+
eot
|
99
|
+
translate(text, :have_header => true).should == <<-eot
|
100
|
+
# @title Bonjour (Hello in fr)
|
101
|
+
|
102
|
+
# Getting Started with YARD
|
103
|
+
|
104
|
+
Paragraph.
|
105
|
+
eot
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should ignore markup line" do
|
109
|
+
text = <<-eot
|
110
|
+
#!markdown
|
111
|
+
# @title Hello
|
112
|
+
|
113
|
+
# Getting Started with YARD
|
114
|
+
|
115
|
+
Paragraph.
|
116
|
+
eot
|
117
|
+
translate(text, :have_header => true).should == <<-eot
|
118
|
+
#!markdown
|
119
|
+
# @title Bonjour (Hello in fr)
|
120
|
+
|
121
|
+
# Getting Started with YARD
|
122
|
+
|
123
|
+
Paragraph.
|
124
|
+
eot
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe "Body" do
|
129
|
+
it "should split to paragraphs" do
|
130
|
+
paragraph1 = <<-eop.strip
|
131
|
+
Paragraph 1.
|
132
|
+
eop
|
133
|
+
paragraph2 = <<-eop.strip
|
134
|
+
Paragraph 2.
|
135
|
+
eop
|
136
|
+
text = <<-eot
|
137
|
+
#{paragraph1}
|
138
|
+
|
139
|
+
#{paragraph2}
|
140
|
+
eot
|
141
|
+
translate(text).should == <<-eot
|
142
|
+
Paragraphe 1.
|
143
|
+
|
144
|
+
Paragraphe 2.
|
145
|
+
eot
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should not modified non-translated message" do
|
149
|
+
nonexistent_paragraph = <<-eop.strip
|
150
|
+
Nonexsitent paragraph.
|
151
|
+
eop
|
152
|
+
text = <<-eot
|
153
|
+
#{nonexistent_paragraph}
|
154
|
+
eot
|
155
|
+
translate(text).should == <<-eot
|
156
|
+
#{nonexistent_paragraph}
|
157
|
+
eot
|
158
|
+
end
|
159
|
+
|
160
|
+
it "should keep empty lines" do
|
161
|
+
text = <<-eot
|
162
|
+
Paragraph 1.
|
163
|
+
|
164
|
+
|
165
|
+
|
166
|
+
|
167
|
+
Paragraph 2.
|
168
|
+
eot
|
169
|
+
translate(text).should == <<-eot
|
170
|
+
Paragraphe 1.
|
171
|
+
|
172
|
+
|
173
|
+
|
174
|
+
|
175
|
+
Paragraphe 2.
|
176
|
+
eot
|
177
|
+
end
|
69
178
|
end
|
70
179
|
end
|
71
180
|
end
|
data/spec/logging_spec.rb
CHANGED
@@ -11,4 +11,25 @@ describe YARD::Logger do
|
|
11
11
|
log.show_backtraces.should == false
|
12
12
|
end
|
13
13
|
end
|
14
|
+
|
15
|
+
describe '#backtrace' do
|
16
|
+
before { log.show_backtraces = true }
|
17
|
+
after { log.show_backtraces = false }
|
18
|
+
|
19
|
+
it "should log backtrace in error by default" do
|
20
|
+
log.should_receive(:error).with("RuntimeError: foo")
|
21
|
+
log.should_receive(:error).with("Stack trace:\n\tline1\n\tline2\n")
|
22
|
+
exc = RuntimeError.new("foo")
|
23
|
+
exc.set_backtrace(['line1', 'line2'])
|
24
|
+
log.enter_level(Logger::INFO) { log.backtrace(exc) }
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should allow backtrace to be entered in other modes" do
|
28
|
+
log.should_receive(:warn).with("RuntimeError: foo")
|
29
|
+
log.should_receive(:warn).with("Stack trace:\n\tline1\n\tline2\n")
|
30
|
+
exc = RuntimeError.new("foo")
|
31
|
+
exc.set_backtrace(['line1', 'line2'])
|
32
|
+
log.enter_level(Logger::INFO) { log.backtrace(exc, :warn) }
|
33
|
+
end
|
34
|
+
end
|
14
35
|
end
|
@@ -85,6 +85,42 @@ describe YARD::Parser::C::CParser do
|
|
85
85
|
constant.docstring.should == "This constant is frequently used to indicate a\nsoftware crash or deadlock in embedded systems."
|
86
86
|
end
|
87
87
|
end
|
88
|
+
|
89
|
+
describe 'Macros' do
|
90
|
+
it "should handle param## inside of macros" do
|
91
|
+
thr = Thread.new do
|
92
|
+
parse <<-eof
|
93
|
+
void
|
94
|
+
Init_gobject_gparamspecs(void)
|
95
|
+
{
|
96
|
+
VALUE cParamSpec = GTYPE2CLASS(G_TYPE_PARAM);
|
97
|
+
VALUE c;
|
98
|
+
|
99
|
+
#define DEF_NUMERIC_PSPEC_METHODS(c, typename) \
|
100
|
+
G_STMT_START {\
|
101
|
+
rbg_define_method(c, "initialize", typename##_initialize, 7); \
|
102
|
+
rbg_define_method(c, "minimum", typename##_minimum, 0); \
|
103
|
+
rbg_define_method(c, "maximum", typename##_maximum, 0); \
|
104
|
+
rbg_define_method(c, "range", typename##_range, 0); \
|
105
|
+
} G_STMT_END
|
106
|
+
|
107
|
+
#if 0
|
108
|
+
rbg_define_method(c, "default_value", typename##_default_value, 0); \
|
109
|
+
rb_define_alias(c, "default", "default_value"); \
|
110
|
+
|
111
|
+
#endif
|
112
|
+
|
113
|
+
c = G_DEF_CLASS(G_TYPE_PARAM_CHAR, "Char", cParamSpec);
|
114
|
+
DEF_NUMERIC_PSPEC_METHODS(c, char);
|
115
|
+
eof
|
116
|
+
end
|
117
|
+
thr.join(5)
|
118
|
+
if thr.alive?
|
119
|
+
fail "Did not parse in time"
|
120
|
+
thr.kill
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
88
124
|
end
|
89
125
|
|
90
126
|
describe 'Override comments' do
|
@@ -465,7 +465,7 @@ describe YARD::Parser::SourceParser do
|
|
465
465
|
end
|
466
466
|
|
467
467
|
it "should parse a set of absolute paths" do
|
468
|
-
Dir.should_not_receive(:[])
|
468
|
+
Dir.should_not_receive(:[])
|
469
469
|
File.should_receive(:file?).with('/path/to/file').and_return(true)
|
470
470
|
File.should_receive(:read_binary).with('/path/to/file').and_return("")
|
471
471
|
YARD.parse('/path/to/file')
|
@@ -594,13 +594,16 @@ describe YARD::Parser::SourceParser do
|
|
594
594
|
end
|
595
595
|
|
596
596
|
it "should attempt to parse files in order" do
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
597
|
+
log.enter_level(Logger::DEBUG) do
|
598
|
+
msgs = []
|
599
|
+
log.should_receive(:debug) {|m| msgs << m }.at_least(:once)
|
600
|
+
log.stub(:<<)
|
601
|
+
in_order_parse 'parse_in_order_001', 'parse_in_order_002'
|
602
|
+
msgs[1].should =~ /Parsing .+parse_in_order_001.+/
|
603
|
+
msgs[2].should =~ /Missing object MyModule/
|
604
|
+
msgs[3].should =~ /Parsing .+parse_in_order_002.+/
|
605
|
+
msgs[4].should =~ /Re-processing .+parse_in_order_001.+/
|
606
|
+
end
|
604
607
|
end
|
605
608
|
|
606
609
|
it "should attempt to order files by length (process toplevel files first)" do
|
data/spec/registry_spec.rb
CHANGED
@@ -169,6 +169,32 @@ describe YARD::Registry do
|
|
169
169
|
Registry.resolve(P('MyObject'), '#foo', true).should be_nil
|
170
170
|
end
|
171
171
|
|
172
|
+
it "should allow type=:typename to ensure resolved object is of a certain type" do
|
173
|
+
YARD.parse_string "class Foo; end"
|
174
|
+
Registry.resolve(Registry.root, 'Foo').should == Registry.at('Foo')
|
175
|
+
Registry.resolve(Registry.root, 'Foo', false, false, :method).should be_nil
|
176
|
+
end
|
177
|
+
|
178
|
+
it "should allow keep trying to find obj where type equals object type" do
|
179
|
+
YARD.parse_string <<-eof
|
180
|
+
module Foo
|
181
|
+
class Bar; end
|
182
|
+
def self.Bar; end
|
183
|
+
end
|
184
|
+
eof
|
185
|
+
Registry.resolve(P('Foo'), 'Bar').should == Registry.at('Foo::Bar')
|
186
|
+
Registry.resolve(P('Foo'), 'Bar', false, false, :method).should ==
|
187
|
+
Registry.at('Foo.Bar')
|
188
|
+
end
|
189
|
+
|
190
|
+
it "should return proxy fallback with given type if supplied" do
|
191
|
+
YARD.parse_string "module Foo; end"
|
192
|
+
proxy = Registry.resolve(P('Foo'), 'Bar', false, true, :method)
|
193
|
+
proxy.type.should == :method
|
194
|
+
proxy = Registry.resolve(P('Qux'), 'Bar', false, true, :method)
|
195
|
+
proxy.type.should == :method
|
196
|
+
end
|
197
|
+
|
172
198
|
it "should only check 'Path' in lookup on root namespace" do
|
173
199
|
Registry.should_receive(:at).once.with('Test').and_return(true)
|
174
200
|
Registry.resolve(Registry.root, "Test")
|