1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
|
# frozen_string_literal: true
require File.dirname(__FILE__) + '/spec_helper'
RSpec.describe "YARD::Handlers::Ruby::#{LEGACY_PARSER ? "Legacy::" : ""}ConstantHandler" do
before(:all) { parse_file :constant_handler_001, __FILE__ }
it "does not parse constants inside methods" do
expect(Registry.at("A::B::SOMECONSTANT").source).to eq "SOMECONSTANT= \"hello\""
end
it "only parses valid constants" do
expect(Registry.at("A::B::notaconstant")).to be nil
end
it "maintains newlines" do
expect(Registry.at("A::B::MYCONSTANT").value.delete("\r")).to eq "A +\nB +\nC +\nD"
end
it "turns Const = Struct.new(:sym) into class Const with attr :sym" do
obj = Registry.at("MyClass")
expect(obj).to be_kind_of(CodeObjects::ClassObject)
attrs = obj.attributes[:instance]
[:a, :b, :c].each do |key|
expect(attrs).to have_key(key)
expect(attrs[key][:read]).not_to be nil
expect(attrs[key][:write]).not_to be nil
end
end
it 'documents block for Struct.new if present' do
obj = Registry.at("MyStructWithConstant")
expect(obj).to be_kind_of(CodeObjects::ClassObject)
expect(obj.constants[0].docstring).to eq 'A constant.'
expect(obj.constants[0].name).to eq :CONSTANT
expect(obj.constants[0].value).to eq "42"
expect(obj.constants[1].docstring).to eq 'Special constant (empty symbol)'
expect(obj.constants[1].name).to eq :EMPTY
expect(obj.constants[1].value).to eq ":''"
end
it "turns Const = Struct.new('Name', :sym) into class Const with attr :sym" do
obj = Registry.at("NotMyClass")
expect(obj).to be_kind_of(CodeObjects::ClassObject)
attrs = obj.attributes[:instance]
[:b, :c].each do |key|
expect(attrs).to have_key(key)
expect(attrs[key][:read]).not_to be nil
expect(attrs[key][:write]).not_to be nil
end
expect(Registry.at("NotMyClass2")).to be nil
end
it "turns Const = Struct.new into empty struct" do
obj = Registry.at("MyEmptyStruct")
expect(obj).not_to be nil
expect(obj.attributes[:instance]).to be_empty
end
it "turns A::Const = Struct.new(:sym) into class A::Const with attr :sym" do
obj = Registry.at("A::NestedCompactStruct")
expect(obj).to be_kind_of(CodeObjects::ClassObject)
expect(obj.superclass).to eq P(:Struct)
attrs = obj.attributes[:instance]
[:b, :c].each do |key|
expect(attrs).to have_key(key)
expect(attrs[key][:read]).not_to be nil
expect(attrs[key][:write]).not_to be nil
end
end
it "maintains docstrings on structs defined via constants" do
obj = Registry.at("DocstringStruct")
expect(obj).not_to be nil
expect(obj.docstring).to eq "A crazy struct."
expect(obj.attributes[:instance]).not_to be_empty
a1 = Registry.at("DocstringStruct#bar")
a2 = Registry.at("DocstringStruct#baz")
expect(a1.docstring).to eq "An attr"
expect(a1.tag(:return).types).to eq ["String"]
expect(a2.docstring).to eq "Another attr"
expect(a2.tag(:return).types).to eq ["Number"]
a3 = Registry.at("DocstringStruct#new_syntax")
expect(a3.docstring).to eq "Attribute defined with the new syntax"
expect(a3.tag(:return).types).to eq ["Symbol"]
end
it "turns Const = Data.define(:sym) into class Const with attr reader :sym" do
obj = Registry.at("MyData")
expect(obj).to be_kind_of(CodeObjects::ClassObject)
expect(obj.superclass).to eq P(:Data)
attrs = obj.attributes[:instance]
[:a, :b, :c].each do |key|
expect(attrs).to have_key(key)
expect(attrs[key][:read]).not_to be nil
expect(attrs[key][:write]).to be nil
end
end
it "turns Const = Data.define into empty data class" do
obj = Registry.at("MyEmptyData")
expect(obj).to be_kind_of(CodeObjects::ClassObject)
expect(obj.superclass).to eq P(:Data)
expect(obj.attributes[:instance]).to be_empty
end
it "turns A::Const = Data.define(:sym) into class A::Const with attr reader :sym" do
obj = Registry.at("A::NestedCompactData")
expect(obj).to be_kind_of(CodeObjects::ClassObject)
expect(obj.superclass).to eq P(:Data)
attrs = obj.attributes[:instance]
[:b, :c].each do |key|
expect(attrs).to have_key(key)
expect(attrs[key][:read]).not_to be nil
expect(attrs[key][:write]).to be nil
end
end
it "documents block for Data.define if present" do
obj = Registry.at("MyDataWithMethods")
expect(obj).to be_kind_of(CodeObjects::ClassObject)
expect(obj.superclass).to eq P(:Data)
attrs = obj.attributes[:instance]
[:c, :d].each do |key|
expect(attrs).to have_key(key)
expect(attrs[key][:read]).not_to be nil
expect(attrs[key][:write]).to be nil
end
expect(obj.meths).to include(P("MyDataWithMethods#foo"))
end
it "raises undocumentable error in 1.9 parser for Struct.new assignment to non-const" do
undoc_error "nonconst = Struct.new"
end unless LEGACY_PARSER
%w(module class).each do |type|
it "does not allow #{type} to be redefined as constant" do
undoc_error <<-eof
#{type} Foo; end
Foo = "value"
eof
end
end unless LEGACY_PARSER
it "allows constant to have same name as constant in parent namespace" do
YARD.parse_string <<-eof
module A
class C; end
module B; C = 1 end
end
eof
expect(log.io.string).to eq ""
expect(Registry.at('A::B::C').type).to eq :constant
end
it "detects compound constant names" do
YARD.parse_string <<-eof
module A
class AA; end
AA::B = true
end
A::AA::C = true
eof
expect(Registry.at('A::AA::B').type).to eq :constant
expect(Registry.at('A::AA::C').type).to eq :constant
end if HAVE_RIPPER
end
|