spec/handlers/c/method_handler_spec.rb in yard-0.9.18 vs spec/handlers/c/method_handler_spec.rb in yard-0.9.19
- old
+ new
@@ -1,325 +1,327 @@
-# frozen_string_literal: true
-require File.dirname(__FILE__) + "/spec_helper"
-
-RSpec.describe YARD::Handlers::C::MethodHandler do
- it "registers methods" do
- parse_init <<-eof
- mFoo = rb_define_module("Foo");
- rb_define_method(mFoo, "bar", bar, 0);
- eof
- expect(Registry.at('Foo#bar')).not_to be nil
- expect(Registry.at('Foo#bar').visibility).to eq :public
- end
-
- it "registers private methods" do
- parse_init <<-eof
- mFoo = rb_define_module("Foo");
- rb_define_private_method(mFoo, "bar", bar, 0);
- eof
- expect(Registry.at('Foo#bar')).not_to be nil
- expect(Registry.at('Foo#bar').visibility).to eq :private
- end
-
- it "registers singleton methods" do
- parse_init <<-eof
- mFoo = rb_define_module("Foo");
- rb_define_singleton_method(mFoo, "bar", bar, 0);
- eof
- expect(Registry.at('Foo.bar')).not_to be nil
- expect(Registry.at('Foo.bar').visibility).to eq :public
- end
-
- it "registers module functions" do
- parse <<-eof
- /* DOCSTRING
- * @return [String] foo!
- */
- static VALUE bar(VALUE self) { x(); y(); z(); }
-
- void Init_Foo() {
- mFoo = rb_define_module("Foo");
- rb_define_module_function(mFoo, "bar", bar, 0);
- }
- eof
- bar_c = Registry.at('Foo.bar')
- bar_i = Registry.at('Foo#bar')
- expect(bar_c).to be_module_function
- expect(bar_c.visibility).to eq :public
- expect(bar_c.docstring).to eq "DOCSTRING"
- expect(bar_c.tag(:return).object).to eq bar_c
- expect(bar_c.source).to eq "static VALUE bar(VALUE self) { x(); y(); z(); }"
- expect(bar_i).not_to be_module_function
- expect(bar_i.visibility).to eq :private
- expect(bar_i.docstring).to eq "DOCSTRING"
- expect(bar_i.tag(:return).object).to eq bar_i
- expect(bar_i.source).to eq bar_c.source
- end
-
- it "registers global functions into Kernel" do
- parse_init 'rb_define_global_function("bar", bar, 0);'
- expect(Registry.at('Kernel#bar')).not_to be nil
- end
-
- it "looks for symbol containing method source" do
- parse <<-eof
- static VALUE foo(VALUE self) { x(); y(); z(); }
- VALUE bar() { a(); b(); c(); }
- void Init_Foo() {
- mFoo = rb_define_module("Foo");
- rb_define_method(mFoo, "foo", foo, 0);
- rb_define_method(mFoo, "bar", bar, 0);
- }
- eof
- foo = Registry.at('Foo#foo')
- bar = Registry.at('Foo#bar')
- expect(foo.source).to eq "static VALUE foo(VALUE self) { x(); y(); z(); }"
- expect(foo.file).to eq '(stdin)'
- expect(foo.line).to eq 1
- expect(bar.source).to eq "VALUE bar() { a(); b(); c(); }"
- expect(bar.file).to eq '(stdin)'
- expect(bar.line).to eq 2
- end
-
- it "finds docstrings attached to method symbols" do
- parse <<-eof
- /* DOCSTRING */
- static VALUE foo(VALUE self) { x(); y(); z(); }
- void Init_Foo() {
- mFoo = rb_define_module("Foo");
- rb_define_method(mFoo, "foo", foo, 0);
- }
- eof
- foo = Registry.at('Foo#foo')
- expect(foo.docstring).to eq 'DOCSTRING'
- end
-
- it "uses declaration comments as docstring if there are no others" do
- parse <<-eof
- static VALUE foo(VALUE self) { x(); y(); z(); }
- void Init_Foo() {
- mFoo = rb_define_module("Foo");
- /* DOCSTRING */
- rb_define_method(mFoo, "foo", foo, 0);
- // DOCSTRING!
- rb_define_method(mFoo, "bar", bar, 0);
- }
- eof
- foo = Registry.at('Foo#foo')
- expect(foo.docstring).to eq 'DOCSTRING'
- bar = Registry.at('Foo#bar')
- expect(bar.docstring).to eq 'DOCSTRING!'
- end
-
- it "looks for symbols in other file" do
- other = <<-eof
- /* DOCSTRING! */
- static VALUE foo() { x(); }
- eof
- expect(File).to receive(:read).with('other.c').and_return(other)
- parse <<-eof
- void Init_Foo() {
- mFoo = rb_define_module("Foo");
- rb_define_method(mFoo, "foo", foo, 0); // in other.c
- }
- eof
- foo = Registry.at('Foo#foo')
- expect(foo.docstring).to eq 'DOCSTRING!'
- expect(foo.file).to eq 'other.c'
- expect(foo.line).to eq 2
- expect(foo.source).to eq 'static VALUE foo() { x(); }'
- end
-
- it "allows extra file to include /'s and other filename characters" do
- expect(File).to receive(:read).at_least(1).times.with('ext/a-file.c').and_return(<<-eof)
- /* FOO */
- VALUE foo(VALUE x) { int value = x; }
-
- /* BAR */
- VALUE bar(VALUE x) { int value = x; }
- eof
- parse_init <<-eof
- rb_define_method(rb_cFoo, "foo", foo, 1); /* in ext/a-file.c */
- rb_define_global_function("bar", bar, 1); /* in ext/a-file.c */
- eof
- expect(Registry.at('Foo#foo').docstring).to eq 'FOO'
- expect(Registry.at('Kernel#bar').docstring).to eq 'BAR'
- end
-
- it "warns if other file can't be found" do
- expect(log).to receive(:warn).with(/Missing source file `other.c' when parsing Foo#foo/)
- parse <<-eof
- void Init_Foo() {
- mFoo = rb_define_module("Foo");
- rb_define_method(mFoo, "foo", foo, 0); // in other.c
- }
- eof
- end
-
- it "looks at override comments for docstring" do
- parse <<-eof
- /* Document-method: Foo::foo
- * Document-method: new
- * Document-method: Foo::Bar#baz
- * Foo bar!
- */
-
- // init comments
- void Init_Foo() {
- mFoo = rb_define_module("Foo");
- rb_define_method(mFoo, "foo", foo, 0);
- rb_define_method(mFoo, "initialize", foo, 0);
- mBar = rb_define_module_under(mFoo, "Bar");
- rb_define_method(mBar, "baz", foo, 0);
- }
- eof
- expect(Registry.at('Foo#foo').docstring).to eq 'Foo bar!'
- expect(Registry.at('Foo#initialize').docstring).to eq 'Foo bar!'
- expect(Registry.at('Foo::Bar#baz').docstring).to eq 'Foo bar!'
- end
-
- it "looks at overrides in other files" do
- other = <<-eof
- /* Document-method: Foo::foo
- * Document-method: new
- * Document-method: Foo::Bar#baz
- * Foo bar!
- */
- eof
- expect(File).to receive(:read).with('foo/bar/other.c').and_return(other)
- src = <<-eof
- void Init_Foo() {
- mFoo = rb_define_module("Foo");
- rb_define_method(mFoo, "foo", foo, 0); // in foo/bar/other.c
- rb_define_method(mFoo, "initialize", foo, 0); // in foo/bar/other.c
- mBar = rb_define_module_under(mFoo, "Bar"); // in foo/bar/other.c
- rb_define_method(mBar, "baz", foo, 0); // in foo/bar/other.c
- }
- eof
- parse(src, 'foo/bar/baz/init.c')
- expect(Registry.at('Foo#foo').docstring).to eq 'Foo bar!'
- expect(Registry.at('Foo#initialize').docstring).to eq 'Foo bar!'
- expect(Registry.at('Foo::Bar#baz').docstring).to eq 'Foo bar!'
- end
-
- it "adds return tag on methods ending in '?'" do
- parse <<-eof
- /* DOCSTRING */
- static VALUE foo(VALUE self) { x(); y(); z(); }
- void Init_Foo() {
- mFoo = rb_define_module("Foo");
- rb_define_method(mFoo, "foo?", foo, 0);
- }
- eof
- foo = Registry.at('Foo#foo?')
- expect(foo.docstring).to eq 'DOCSTRING'
- expect(foo.tag(:return).types).to eq ['Boolean']
- end
-
- it "does not add return tag if return tags exist" do
- parse <<-eof
- // @return [String] foo
- static VALUE foo(VALUE self) { x(); y(); z(); }
- void Init_Foo() {
- mFoo = rb_define_module("Foo");
- rb_define_method(mFoo, "foo?", foo, 0);
- }
- eof
- foo = Registry.at('Foo#foo?')
- expect(foo.tag(:return).types).to eq ['String']
- end
-
- it "handles casted method names" do
- parse_init <<-eof
- mFoo = rb_define_module("Foo");
- rb_define_method(mFoo, "bar", (METHOD)bar, 0);
- rb_define_global_function("baz", (METHOD)baz, 0);
- eof
- expect(Registry.at('Foo#bar')).not_to be nil
- expect(Registry.at('Kernel#baz')).not_to be nil
- end
-
- it "extracts at regular method parameters from C function signatures" do
- parse <<-eof
- static VALUE noargs_func(VALUE self) { return Qnil; }
- static VALUE twoargs_func(VALUE self, VALUE a, VALUE b) { return a; }
- void Init_Foo() {
- mFoo = rb_define_module("Foo");
- rb_define_method(mFoo, "noargs", noargs_func, 0);
- rb_define_method(mFoo, "twoargs", twoargs_func, 2);
- }
- eof
- expect(Registry.at('Foo#noargs').parameters).to be_empty
- expect(Registry.at('Foo#twoargs').parameters).to eq [['a', nil], ['b', nil]]
- end
-
- it "extracts at varargs method parameters from C function signatures" do
- parse <<-eof
- static VALUE varargs_func(int argc, VALUE *argv, VALUE self) { return self; }
- /* let's see if parser is robust in the face of strange spacing */
- static VALUE varargs_func2( int argc , VALUE
- * argv ,VALUE self )
-
- {return self;}
- void Init_Foo() {
- mFoo = rb_define_module("Foo");
- rb_define_method(mFoo, "varargs", varargs_func, -1);
- rb_define_method( mFoo ,"varargs2",varargs_func2 ,-1);
- }
- eof
- expect(Registry.at('Foo#varargs').parameters).to eq [['*args', nil]]
- expect(Registry.at('Foo#varargs2').parameters).to eq [['*args', nil]]
- end
-
- it "is not too strict or too loose about matching override comments to methods" do
- parse <<-eof
- /* Document-method: Foo::foo
- * Document-method: new
- * Document-method: Foo::Bar#baz
- * Foo bar!
- */
-
- void Init_Foo() {
- mFoo = rb_define_module("Foo");
- mBar = rb_define_module_under(mFoo, "Bar");
-
- rb_define_method(mFoo, "foo", foo, 0);
- rb_define_singleton_method(mFoo, "foo", foo, 0);
- rb_define_method(mBar, "foo", foo, 0);
- rb_define_singleton_method(mBar, "foo", foo, 0);
-
- rb_define_method(mFoo, "initialize", foo, 0);
- rb_define_method(mBar, "initialize", foo, 0);
-
- rb_define_method(mFoo, "baz", foo, 0);
- rb_define_singleton_method(mFoo, "baz", foo, 0);
- rb_define_method(mBar, "baz", foo, 0);
- rb_define_singleton_method(mBar, "baz", foo, 0);
- }
- eof
- expect(Registry.at('Foo#foo').docstring).to eq 'Foo bar!'
- expect(Registry.at('Foo.foo').docstring).to eq 'Foo bar!'
- expect(Registry.at('Foo::Bar#foo').docstring).to be_empty
- expect(Registry.at('Foo::Bar.foo').docstring).to be_empty
- expect(Registry.at('Foo#initialize').docstring).to eq 'Foo bar!'
- expect(Registry.at('Foo::Bar#initialize').docstring).to eq 'Foo bar!'
- expect(Registry.at('Foo#baz').docstring).to be_empty
- expect(Registry.at('Foo.baz').docstring).to be_empty
- expect(Registry.at('Foo::Bar#baz').docstring).to eq 'Foo bar!'
- expect(Registry.at('Foo::Bar.baz').docstring).to be_empty
- end
-
- it "recognizes core Ruby classes and modules provided by ruby.h" do
- parse_init <<-eof
- rb_define_method(rb_cFixnum, "popcount", fix_popcount, 0);
- rb_define_private_method(rb_mKernel, "pp", obj_pp, 0);
- rb_define_method(rb_mEnumerable, "to_hash", enum_to_hash, 0);
- eof
- expect(Registry.at('Fixnum').type).to eq :class
- expect(Registry.at('Fixnum#popcount').type).to eq :method
- expect(Registry.at('Object').type).to eq :class
- # Methods defined on Kernel are treated as if they were defined on Object
- expect(Registry.at('Object#pp').type).to eq :method
- expect(Registry.at('Enumerable').type).to eq :module
- expect(Registry.at('Enumerable#to_hash').type).to eq :method
- end
-end
+# frozen_string_literal: true
+require File.dirname(__FILE__) + "/spec_helper"
+
+RSpec.describe YARD::Handlers::C::MethodHandler do
+ it "registers methods" do
+ parse_init <<-eof
+ mFoo = rb_define_module("Foo");
+ rb_define_method(mFoo, "bar", bar, 0);
+ eof
+ expect(Registry.at('Foo#bar')).not_to be nil
+ expect(Registry.at('Foo#bar').visibility).to eq :public
+ end
+
+ it "registers private methods" do
+ parse_init <<-eof
+ mFoo = rb_define_module("Foo");
+ rb_define_private_method(mFoo, "bar", bar, 0);
+ eof
+ expect(Registry.at('Foo#bar')).not_to be nil
+ expect(Registry.at('Foo#bar').visibility).to eq :private
+ end
+
+ it "registers singleton methods" do
+ parse_init <<-eof
+ mFoo = rb_define_module("Foo");
+ rb_define_singleton_method(mFoo, "bar", bar, 0);
+ eof
+ expect(Registry.at('Foo.bar')).not_to be nil
+ expect(Registry.at('Foo.bar').visibility).to eq :public
+ end
+
+ it "registers module functions" do
+ parse <<-eof
+ /* DOCSTRING
+ * @return [String] foo!
+ */
+ static VALUE bar(VALUE self) { x(); y(); z(); }
+
+ void Init_Foo() {
+ mFoo = rb_define_module("Foo");
+ rb_define_module_function(mFoo, "bar", bar, 0);
+ }
+ eof
+ bar_c = Registry.at('Foo.bar')
+ bar_i = Registry.at('Foo#bar')
+ expect(bar_c).to be_module_function
+ expect(bar_c.visibility).to eq :public
+ expect(bar_c.docstring).to eq "DOCSTRING"
+ expect(bar_c.tag(:return).object).to eq bar_c
+ expect(bar_c.source).to eq "static VALUE bar(VALUE self) { x(); y(); z(); }"
+ expect(bar_i).not_to be_module_function
+ expect(bar_i.visibility).to eq :private
+ expect(bar_i.docstring).to eq "DOCSTRING"
+ expect(bar_i.tag(:return).object).to eq bar_i
+ expect(bar_i.source).to eq bar_c.source
+ end
+
+ it "registers global functions into Kernel" do
+ parse_init 'rb_define_global_function("bar", bar, 0);'
+ expect(Registry.at('Kernel#bar')).not_to be nil
+ end
+
+ it "looks for symbol containing method source" do
+ parse <<-eof
+ static VALUE foo(VALUE self) { x(); y(); z(); }
+ VALUE bar() { a(); b(); c(); }
+ void Init_Foo() {
+ mFoo = rb_define_module("Foo");
+ rb_define_method(mFoo, "foo", foo, 0);
+ rb_define_method(mFoo, "bar", bar, 0);
+ }
+ eof
+ foo = Registry.at('Foo#foo')
+ bar = Registry.at('Foo#bar')
+ expect(foo.source).to eq "static VALUE foo(VALUE self) { x(); y(); z(); }"
+ expect(foo.file).to eq '(stdin)'
+ expect(foo.line).to eq 1
+ expect(bar.source).to eq "VALUE bar() { a(); b(); c(); }"
+ expect(bar.file).to eq '(stdin)'
+ expect(bar.line).to eq 2
+ end
+
+ it "finds docstrings attached to method symbols" do
+ parse <<-eof
+ /* DOCSTRING */
+ static VALUE foo(VALUE self) { x(); y(); z(); }
+ void Init_Foo() {
+ mFoo = rb_define_module("Foo");
+ rb_define_method(mFoo, "foo", foo, 0);
+ }
+ eof
+ foo = Registry.at('Foo#foo')
+ expect(foo.docstring).to eq 'DOCSTRING'
+ end
+
+ it "uses declaration comments as docstring if there are no others" do
+ parse <<-eof
+ static VALUE foo(VALUE self) { x(); y(); z(); }
+ void Init_Foo() {
+ mFoo = rb_define_module("Foo");
+ /* DOCSTRING */
+ rb_define_method(mFoo, "foo", foo, 0);
+ // DOCSTRING!
+ rb_define_method(mFoo, "bar", bar, 0);
+ }
+ eof
+ foo = Registry.at('Foo#foo')
+ expect(foo.docstring).to eq 'DOCSTRING'
+ bar = Registry.at('Foo#bar')
+ expect(bar.docstring).to eq 'DOCSTRING!'
+ end
+
+ it "looks for symbols in other file" do
+ other = <<-eof
+ /* DOCSTRING! */
+ static VALUE foo() { x(); }
+ eof
+ expect(File).to receive(:read).with('other.c').and_return(other)
+ parse <<-eof
+ void Init_Foo() {
+ mFoo = rb_define_module("Foo");
+ rb_define_method(mFoo, "foo", foo, 0); // in other.c
+ }
+ eof
+ foo = Registry.at('Foo#foo')
+ expect(foo.docstring).to eq 'DOCSTRING!'
+ expect(foo.file).to eq 'other.c'
+ expect(foo.line).to eq 2
+ expect(foo.source).to eq 'static VALUE foo() { x(); }'
+ end
+
+ it "allows extra file to include /'s and other filename characters" do
+ expect(File).to receive(:read).at_least(1).times.with('ext/a-file.c').and_return(<<-eof)
+ /* FOO */
+ VALUE foo(VALUE x) { int value = x; }
+
+ /* BAR */
+ VALUE bar(VALUE x) { int value = x; }
+ eof
+ parse_init <<-eof
+ rb_define_method(rb_cFoo, "foo", foo, 1); /* in ext/a-file.c */
+ rb_define_global_function("bar", bar, 1); /* in ext/a-file.c */
+ eof
+ expect(Registry.at('Foo#foo').docstring).to eq 'FOO'
+ expect(Registry.at('Kernel#bar').docstring).to eq 'BAR'
+ end
+
+ it "warns if other file can't be found" do
+ expect(log).to receive(:warn).with(/Missing source file `other.c' when parsing Foo#foo/)
+ parse <<-eof
+ void Init_Foo() {
+ mFoo = rb_define_module("Foo");
+ rb_define_method(mFoo, "foo", foo, 0); // in other.c
+ }
+ eof
+ end
+
+ it "looks at override comments for docstring" do
+ parse <<-eof
+ /* Document-method: Foo::foo
+ * Document-method: new
+ * Document-method: Foo::Bar#baz
+ * Foo bar!
+ */
+
+ // init comments
+ void Init_Foo() {
+ mFoo = rb_define_module("Foo");
+ rb_define_method(mFoo, "foo", foo, 0);
+ rb_define_method(mFoo, "initialize", foo, 0);
+ mBar = rb_define_module_under(mFoo, "Bar");
+ rb_define_method(mBar, "baz", foo, 0);
+ }
+ eof
+ expect(Registry.at('Foo#foo').docstring).to eq 'Foo bar!'
+ expect(Registry.at('Foo#initialize').docstring).to eq 'Foo bar!'
+ expect(Registry.at('Foo::Bar#baz').docstring).to eq 'Foo bar!'
+ end
+
+ it "looks at overrides in other files" do
+ other = <<-eof
+ /* Document-method: Foo::foo
+ * Document-method: new
+ * Document-method: Foo::Bar#baz
+ * Foo bar!
+ */
+ eof
+ expect(File).to receive(:read).with('foo/bar/other.c').and_return(other)
+ src = <<-eof
+ void Init_Foo() {
+ mFoo = rb_define_module("Foo");
+ rb_define_method(mFoo, "foo", foo, 0); // in foo/bar/other.c
+ rb_define_method(mFoo, "initialize", foo, 0); // in foo/bar/other.c
+ mBar = rb_define_module_under(mFoo, "Bar"); // in foo/bar/other.c
+ rb_define_method(mBar, "baz", foo, 0); // in foo/bar/other.c
+ }
+ eof
+ parse(src, 'foo/bar/baz/init.c')
+ expect(Registry.at('Foo#foo').docstring).to eq 'Foo bar!'
+ expect(Registry.at('Foo#initialize').docstring).to eq 'Foo bar!'
+ expect(Registry.at('Foo::Bar#baz').docstring).to eq 'Foo bar!'
+ end
+
+ it "adds return tag on methods ending in '?'" do
+ parse <<-eof
+ /* DOCSTRING */
+ static VALUE foo(VALUE self) { x(); y(); z(); }
+ void Init_Foo() {
+ mFoo = rb_define_module("Foo");
+ rb_define_method(mFoo, "foo?", foo, 0);
+ }
+ eof
+ foo = Registry.at('Foo#foo?')
+ expect(foo.docstring).to eq 'DOCSTRING'
+ expect(foo.tag(:return).types).to eq ['Boolean']
+ expect(foo.tags(:return).size).to eq 1
+ end
+
+ it "does not add return tag if return tags exist" do
+ parse <<-eof
+ // @return [String] foo
+ static VALUE foo(VALUE self) { x(); y(); z(); }
+ void Init_Foo() {
+ mFoo = rb_define_module("Foo");
+ rb_define_method(mFoo, "foo?", foo, 0);
+ }
+ eof
+ foo = Registry.at('Foo#foo?')
+ expect(foo.tag(:return).types).to eq ['String']
+ expect(foo.tags(:return).size).to eq 1
+ end
+
+ it "handles casted method names" do
+ parse_init <<-eof
+ mFoo = rb_define_module("Foo");
+ rb_define_method(mFoo, "bar", (METHOD)bar, 0);
+ rb_define_global_function("baz", (METHOD)baz, 0);
+ eof
+ expect(Registry.at('Foo#bar')).not_to be nil
+ expect(Registry.at('Kernel#baz')).not_to be nil
+ end
+
+ it "extracts at regular method parameters from C function signatures" do
+ parse <<-eof
+ static VALUE noargs_func(VALUE self) { return Qnil; }
+ static VALUE twoargs_func(VALUE self, VALUE a, VALUE b) { return a; }
+ void Init_Foo() {
+ mFoo = rb_define_module("Foo");
+ rb_define_method(mFoo, "noargs", noargs_func, 0);
+ rb_define_method(mFoo, "twoargs", twoargs_func, 2);
+ }
+ eof
+ expect(Registry.at('Foo#noargs').parameters).to be_empty
+ expect(Registry.at('Foo#twoargs').parameters).to eq [['a', nil], ['b', nil]]
+ end
+
+ it "extracts at varargs method parameters from C function signatures" do
+ parse <<-eof
+ static VALUE varargs_func(int argc, VALUE *argv, VALUE self) { return self; }
+ /* let's see if parser is robust in the face of strange spacing */
+ static VALUE varargs_func2( int argc , VALUE
+ * argv ,VALUE self )
+
+ {return self;}
+ void Init_Foo() {
+ mFoo = rb_define_module("Foo");
+ rb_define_method(mFoo, "varargs", varargs_func, -1);
+ rb_define_method( mFoo ,"varargs2",varargs_func2 ,-1);
+ }
+ eof
+ expect(Registry.at('Foo#varargs').parameters).to eq [['*args', nil]]
+ expect(Registry.at('Foo#varargs2').parameters).to eq [['*args', nil]]
+ end
+
+ it "is not too strict or too loose about matching override comments to methods" do
+ parse <<-eof
+ /* Document-method: Foo::foo
+ * Document-method: new
+ * Document-method: Foo::Bar#baz
+ * Foo bar!
+ */
+
+ void Init_Foo() {
+ mFoo = rb_define_module("Foo");
+ mBar = rb_define_module_under(mFoo, "Bar");
+
+ rb_define_method(mFoo, "foo", foo, 0);
+ rb_define_singleton_method(mFoo, "foo", foo, 0);
+ rb_define_method(mBar, "foo", foo, 0);
+ rb_define_singleton_method(mBar, "foo", foo, 0);
+
+ rb_define_method(mFoo, "initialize", foo, 0);
+ rb_define_method(mBar, "initialize", foo, 0);
+
+ rb_define_method(mFoo, "baz", foo, 0);
+ rb_define_singleton_method(mFoo, "baz", foo, 0);
+ rb_define_method(mBar, "baz", foo, 0);
+ rb_define_singleton_method(mBar, "baz", foo, 0);
+ }
+ eof
+ expect(Registry.at('Foo#foo').docstring).to eq 'Foo bar!'
+ expect(Registry.at('Foo.foo').docstring).to eq 'Foo bar!'
+ expect(Registry.at('Foo::Bar#foo').docstring).to be_empty
+ expect(Registry.at('Foo::Bar.foo').docstring).to be_empty
+ expect(Registry.at('Foo#initialize').docstring).to eq 'Foo bar!'
+ expect(Registry.at('Foo::Bar#initialize').docstring).to eq 'Foo bar!'
+ expect(Registry.at('Foo#baz').docstring).to be_empty
+ expect(Registry.at('Foo.baz').docstring).to be_empty
+ expect(Registry.at('Foo::Bar#baz').docstring).to eq 'Foo bar!'
+ expect(Registry.at('Foo::Bar.baz').docstring).to be_empty
+ end
+
+ it "recognizes core Ruby classes and modules provided by ruby.h" do
+ parse_init <<-eof
+ rb_define_method(rb_cFixnum, "popcount", fix_popcount, 0);
+ rb_define_private_method(rb_mKernel, "pp", obj_pp, 0);
+ rb_define_method(rb_mEnumerable, "to_hash", enum_to_hash, 0);
+ eof
+ expect(Registry.at('Fixnum').type).to eq :class
+ expect(Registry.at('Fixnum#popcount').type).to eq :method
+ expect(Registry.at('Object').type).to eq :class
+ # Methods defined on Kernel are treated as if they were defined on Object
+ expect(Registry.at('Object#pp').type).to eq :method
+ expect(Registry.at('Enumerable').type).to eq :module
+ expect(Registry.at('Enumerable#to_hash').type).to eq :method
+ end
+end