diff options
author | Mike Dalessio <[email protected]> | 2024-10-17 16:40:30 -0400 |
---|---|---|
committer | git <[email protected]> | 2024-10-17 20:40:34 +0000 |
commit | 0b38e184881839d347a777e82ad1b037a1aeca6e (patch) | |
tree | 8b71f0e8b97983d5b97c5772032adfd1c05250b6 /test/rdoc/test_rdoc_class_module.rb | |
parent | 48899d56a9c61d4a3e5fe822ed7c16a1f2868bd4 (diff) |
[ruby/rdoc] feature: Render mixed-in methods and constants with
`--embed-mixins`
(https://github.com/ruby/rdoc/pull/842)
* Embed mixed-in methods and constants with `--embed-mixins`
When `--embed-mixins` option is set:
- methods from an `extend`ed module are documented as singleton methods
- attrs from an `extend`ed module are documented as class attributes
- methods from an `include`ed module are documented as instance methods
- attrs from an `include`ed module are documented as instance attributes
- constants from an `include`ed module are documented
Sections are created when needed, and Darkfish's template annotates
each of these mixed-in CodeObjects. We also respect the mixin methods'
visibility.
This feature is inspired by Yard's option of the same name.
* Add comment to document why we set object visibility
Co-authored-by: Stan Lo <[email protected]>
* Add the mixin_from attribute to CodeObject's initializer
* Add test coverage for private mixed-in attributes.
---------
https://github.com/ruby/rdoc/commit/481c2ce660
Co-authored-by: Stan Lo <[email protected]>
Diffstat (limited to 'test/rdoc/test_rdoc_class_module.rb')
-rw-r--r-- | test/rdoc/test_rdoc_class_module.rb | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/test/rdoc/test_rdoc_class_module.rb b/test/rdoc/test_rdoc_class_module.rb index 27d37cb7dd..d70a3ea033 100644 --- a/test/rdoc/test_rdoc_class_module.rb +++ b/test/rdoc/test_rdoc_class_module.rb @@ -1500,4 +1500,140 @@ class TestRDocClassModule < XrefTestCase assert_equal [a, c], @c1.extends end + class TestRDocClassModuleMixins < XrefTestCase + def setup + super + + klass_tl = @store.add_file("klass.rb") + @klass = klass_tl.add_class(RDoc::NormalClass, "Klass") + + incmod_tl = @store.add_file("incmod.rb") + @incmod = incmod_tl.add_module(RDoc::NormalModule, "Incmod") + + incmod_const = @incmod.add_constant(RDoc::Constant.new("INCMOD_CONST_WITHOUT_A_SECTION", nil, "")) + incmod_const = @incmod.add_constant(RDoc::Constant.new("INCMOD_CONST", nil, "")) + incmod_const.section = @incmod.add_section("Incmod const section") + + incmod_method = @incmod.add_method(RDoc::AnyMethod.new(nil, "incmod_method_without_a_section")) + incmod_method = @incmod.add_method(RDoc::AnyMethod.new(nil, "incmod_method")) + incmod_method.section = @incmod.add_section("Incmod method section") + + incmod_attr = @incmod.add_attribute(RDoc::Attr.new(nil, "incmod_attr_without_a_section", "RW", "")) + incmod_attr = @incmod.add_attribute(RDoc::Attr.new(nil, "incmod_attr", "RW", "")) + incmod_attr.section = @incmod.add_section("Incmod attr section") + + incmod_private_method = @incmod.add_method(RDoc::AnyMethod.new(nil, "incmod_private_method")) + incmod_private_method.visibility = :private + + incmod_private_attr = @incmod.add_attribute(RDoc::Attr.new(nil, "incmod_private_attr", "RW", "")) + incmod_private_attr.visibility = :private + + extmod_tl = @store.add_file("extmod.rb") + @extmod = extmod_tl.add_module(RDoc::NormalModule, "Extmod") + + extmod_method = @extmod.add_method(RDoc::AnyMethod.new(nil, "extmod_method_without_a_section")) + extmod_method = @extmod.add_method(RDoc::AnyMethod.new(nil, "extmod_method")) + extmod_method.section = @extmod.add_section("Extmod method section") + + extmod_attr = @extmod.add_attribute(RDoc::Attr.new(nil, "extmod_attr_without_a_section", "RW", "", true)) + extmod_attr = @extmod.add_attribute(RDoc::Attr.new(nil, "extmod_attr", "RW", "", true)) + extmod_attr.section = @extmod.add_section("Extmod attr section") + + extmod_private_method = @extmod.add_method(RDoc::AnyMethod.new(nil, "extmod_private_method")) + extmod_private_method.visibility = :private + + extmod_private_attr = @extmod.add_attribute(RDoc::Attr.new(nil, "extmod_private_attr", "RW", "", true)) + extmod_private_attr.visibility = :private + + @klass.add_include(RDoc::Include.new("Incmod", nil)) + @klass.add_extend(RDoc::Include.new("Extmod", nil)) + + @klass.add_include(RDoc::Include.new("ExternalInclude", nil)) + @klass.add_extend(RDoc::Include.new("ExternalExtend", nil)) + end + + def test_embed_mixin_when_false_does_not_embed_anything + assert_false(@klass.options.embed_mixins) + @klass.complete(:protected) + + refute_includes(@klass.constants.map(&:name), "INCMOD_CONST") + refute_includes(@klass.method_list.map(&:name), "incmod_method") + refute_includes(@klass.method_list.map(&:name), "extmod_method") + refute_includes(@klass.attributes.map(&:name), "incmod_attr") + refute_includes(@klass.attributes.map(&:name), "extmod_attr") + end + + def test_embed_mixin_when_true_embeds_methods_and_constants + @klass.options.embed_mixins = true + @klass.complete(:protected) + + # assert on presence and identity of methods and constants + constant = @klass.constants.find { |c| c.name == "INCMOD_CONST" } + assert(constant, "constant from included mixin should be present") + assert_equal(@incmod, constant.mixin_from) + + instance_method = @klass.method_list.find { |m| m.name == "incmod_method" } + assert(instance_method, "instance method from included mixin should be present") + refute(instance_method.singleton) + assert_equal(@incmod, instance_method.mixin_from) + + instance_attr = @klass.attributes.find { |a| a.name == "incmod_attr" } + assert(instance_attr, "instance attr from included mixin should be present") + refute(instance_attr.singleton) + assert_equal(@incmod, instance_attr.mixin_from) + + refute(@klass.method_list.find { |m| m.name == "incmod_private_method" }) + refute(@klass.attributes.find { |m| m.name == "incmod_private_attr" }) + + class_method = @klass.method_list.find { |m| m.name == "extmod_method" } + assert(class_method, "class method from extended mixin should be present") + assert(class_method.singleton) + assert_equal(@extmod, class_method.mixin_from) + + class_attr = @klass.attributes.find { |a| a.name == "extmod_attr" } + assert(class_attr, "class attr from extended mixin should be present") + assert(class_attr.singleton) + assert_equal(@extmod, class_attr.mixin_from) + + refute(@klass.method_list.find { |m| m.name == "extmod_private_method" }) + refute(@klass.attributes.find { |m| m.name == "extmod_private_attr" }) + + # assert that sections are also imported + constant_section = @klass.sections.find { |s| s.title == "Incmod const section" } + assert(constant_section, "constant from included mixin should have a section") + assert_equal(constant_section, constant.section) + + instance_method_section = @klass.sections.find { |s| s.title == "Incmod method section" } + assert(instance_method_section, "instance method from included mixin should have a section") + assert_equal(instance_method_section, instance_method.section) + + instance_attr_section = @klass.sections.find { |s| s.title == "Incmod attr section" } + assert(instance_attr_section, "instance attr from included mixin should have a section") + assert_equal(instance_attr_section, instance_attr.section) + + class_method_section = @klass.sections.find { |s| s.title == "Extmod method section" } + assert(class_method_section, "class method from extended mixin should have a section") + assert_equal(class_method_section, class_method.section) + + class_attr_section = @klass.sections.find { |s| s.title == "Extmod attr section" } + assert(class_attr_section, "class attr from extended mixin should have a section") + assert_equal(class_attr_section, class_attr.section) + + # and check that code objects without a section still have no section + constant = @klass.constants.find { |c| c.name == "INCMOD_CONST_WITHOUT_A_SECTION" } + assert_nil(constant.section.title) + + instance_method = @klass.method_list.find { |c| c.name == "incmod_method_without_a_section" } + assert_nil(instance_method.section.title) + + instance_attr = @klass.attributes.find { |c| c.name == "incmod_attr_without_a_section" } + assert_nil(instance_attr.section.title) + + class_method = @klass.method_list.find { |c| c.name == "extmod_method_without_a_section" } + assert_nil(class_method.section.title) + + class_attr = @klass.attributes.find { |c| c.name == "extmod_attr_without_a_section" } + assert_nil(class_attr.section.title) + end + end end |