Skip to content

Commit

Permalink
Unit Tests
Browse files Browse the repository at this point in the history
- Added unit tests for all declarations
- Currently, classes, modules, methods, aliases, attributes, includes, extends are supported and have been tested
  • Loading branch information
raosush committed Jul 22, 2022
1 parent a3a2637 commit 5a56646
Show file tree
Hide file tree
Showing 4 changed files with 277 additions and 22 deletions.
6 changes: 4 additions & 2 deletions lib/rdoc/parser/rbs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,18 @@ class RBS < Parser
parse_files_matching(/\.rbs$/)

def scan
RBS::RDocPlugin::RBSParser.new(@top_level, @content).scan
::RBS::RDocPlugin::Parser.new(@top_level, @content).scan
end
end
end
end

module RBS
module RDocPlugin
class RBSParser
class Parser

attr_reader :top_level, :content

def initialize(top_level, content)
@top_level = top_level
@content = content
Expand Down
36 changes: 20 additions & 16 deletions sig/rdoc/rbs.rbs
Original file line number Diff line number Diff line change
@@ -1,31 +1,35 @@
class RDoc::Parser::RBS < RDoc::Parser
type allowed_decls = RBS::AST::Declarations::Class | RBS::AST::Declarations::Module | RBS::AST::Declarations::Constant | RBS::AST::Members::MethodDefinition | RBS::AST::Members::AttrReader | RBS::AST::Members::AttrAccessor | RBS::AST::Members::AttrWriter | RBS::AST::Members::Include | RBS::AST::Members::Extend
module RBS
module RDocPlugin
class Parser
type allowed_decls = RBS::AST::Declarations::Class | RBS::AST::Declarations::Module | RBS::AST::Declarations::Constant | RBS::AST::Members::MethodDefinition | RBS::AST::Members::AttrReader | RBS::AST::Members::AttrAccessor | RBS::AST::Members::AttrWriter | RBS::AST::Members::Include | RBS::AST::Members::Extend

def initialize: (RDoc::TopLevel top_level, String filename, String content, Hash[untyped, untyped] options, RDoc::Stats stats) -> void
def initialize: (RDoc::TopLevel top_level, String content) -> void

def scan: () -> RDoc::TopLevel
def scan: () -> RDoc::TopLevel

def parse_member: (decl: RBS::AST::Declarations::t | RBS::AST::Members::t, context: RDoc::Context, ?outer_name: RBS::TypeName?) -> void
def parse_member: (decl: RBS::AST::Declarations::t | RBS::AST::Members::t, context: RDoc::Context, ?outer_name: RBS::TypeName?) -> void

def parse_class_decl: (decl: RBS::AST::Declarations::Class, context: RDoc::Context, ?outer_name: RBS::TypeName?) -> void
def parse_class_decl: (decl: RBS::AST::Declarations::Class, context: RDoc::Context, ?outer_name: RBS::TypeName?) -> void

def parse_module_decl: (decl: RBS::AST::Declarations::Module | RBS::AST::Declarations::Interface, context: RDoc::Context, ?outer_name: RBS::TypeName?) -> void
def parse_module_decl: (decl: RBS::AST::Declarations::Module | RBS::AST::Declarations::Interface, context: RDoc::Context, ?outer_name: RBS::TypeName?) -> void

def parse_constant_decl: (decl: RBS::AST::Declarations::Constant, context: RDoc::Context, ?outer_name: RBS::TypeName?) -> void
def parse_constant_decl: (decl: RBS::AST::Declarations::Constant, context: RDoc::Context, ?outer_name: RBS::TypeName?) -> void

def parse_method_decl: (decl: RBS::AST::Members::MethodDefinition, context: RDoc::Context, ?outer_name: RBS::TypeName?) -> void
def parse_method_decl: (decl: RBS::AST::Members::MethodDefinition, context: RDoc::Context, ?outer_name: RBS::TypeName?) -> void

def parse_method_alias_decl: (decl: RBS::AST::Members::Alias, context: RDoc::Context, ?outer_name: RBS::TypeName?) -> void
def parse_method_alias_decl: (decl: RBS::AST::Members::Alias, context: RDoc::Context, ?outer_name: RBS::TypeName?) -> void

def parse_attr_decl: (decl: RBS::AST::Members::AttrReader | RBS::AST::Members::AttrAccessor | RBS::AST::Members::AttrWriter, context: RDoc::Context, ?outer_name: RBS::TypeName?) -> void
def parse_attr_decl: (decl: RBS::AST::Members::AttrReader | RBS::AST::Members::AttrAccessor | RBS::AST::Members::AttrWriter, context: RDoc::Context, ?outer_name: RBS::TypeName?) -> void

def parse_include_decl: (decl: RBS::AST::Members::Include, context: RDoc::Context, ?outer_name: RBS::TypeName?) -> void
def parse_include_decl: (decl: RBS::AST::Members::Include, context: RDoc::Context, ?outer_name: RBS::TypeName?) -> void

def parse_extend_decl: (decl: RBS::AST::Members::Extend, context: RDoc::Context, ?outer_name: RBS::TypeName?) -> void
def parse_extend_decl: (decl: RBS::AST::Members::Extend, context: RDoc::Context, ?outer_name: RBS::TypeName?) -> void

private
private

def construct_comment: (context: RDoc::Context, comment: String) -> RDoc::Comment
def construct_comment: (context: RDoc::Context, comment: String) -> RDoc::Comment

def fully_qualified_name: (outer_name: RBS::TypeName?, decl: allowed_decls) -> RBS::TypeName
def fully_qualified_name: (outer_name: RBS::TypeName?, decl: allowed_decls) -> RBS::TypeName
end
end
end
3 changes: 3 additions & 0 deletions stdlib/rdoc/0/rdoc.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ module RDoc
def initialize: (RDoc::TopLevel top_level, String filename, String content, Hash[untyped, untyped] options, RDoc::Stats stats) -> void

def scan: () -> RDoc::TopLevel

class RBS < Parser
end
end

class CodeObject
Expand Down
254 changes: 250 additions & 4 deletions test/rbs/rdoc/rbs_parser_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def parser(content)
top_level = RDoc::TopLevel.new("a.rbs")
top_level.store = RDoc::Store.new()

RBS::RDocPlugin::RBSParser.new(top_level, content)
RBS::RDocPlugin::Parser.new(top_level, content)
end

def teardown
Expand Down Expand Up @@ -103,7 +103,7 @@ def foo: (Integer) -> void
top_level = parser.top_level

klass = top_level.find_class_or_module("A")
method = klass.method_list.find {|m| m.name == "foo" }
method = klass.method_list.find { |m| m.name == "foo" }

assert_instance_of RDoc::AnyMethod, method
assert_equal "", method.comment
Expand All @@ -122,7 +122,7 @@ def foo: (Integer) { (String) -> void } -> void
top_level = parser.top_level

klass = top_level.find_class_or_module("A")
method = klass.method_list.find {|m| m.name == "foo" }
method = klass.method_list.find { |m| m.name == "foo" }

assert_instance_of RDoc::AnyMethod, method
assert_equal "", method.comment
Expand All @@ -141,10 +141,256 @@ def foo: [A] (Integer) { (String) -> A } -> A
top_level = parser.top_level

klass = top_level.find_class_or_module("A")
method = klass.method_list.find {|m| m.name == "foo" }
method = klass.method_list.find { |m| m.name == "foo" }

assert_instance_of RDoc::AnyMethod, method
assert_equal "", method.comment
assert_equal "foo[A] (Integer) { (String) -> A } -> A", method.call_seq
end

def test_instance_method_comment_and_tokens
parser = parser(<<~RBS)
class A
# Added comment for foo
def foo: [A] (Integer) { (String) -> A } -> A
end
RBS

parser.scan()

top_level = parser.top_level

klass = top_level.find_class_or_module("A")
method = klass.method_list.find { |m| m.name == "foo" }

assert_instance_of RDoc::AnyMethod, method
assert_equal "Added comment for foo", method.comment.text
assert_equal "foo[A] (Integer) { (String) -> A } -> A", method.call_seq
assert_equal "# File a.rbs, line(s) 3:3\n" + "def foo: [A] (Integer) { (String) -> A } -> A", method.tokens_to_s
end

def test_constant_decl_1
parser = parser(<<~RBS)
class A
CONSTANT: Integer
end
RBS

parser.scan()

top_level = parser.top_level

klass = top_level.find_class_or_module("A")
constant = klass.constants.first

assert_instance_of RDoc::Constant, constant
assert_equal "CONSTANT", constant.name
assert_equal "Integer", constant.value
assert_equal "", constant.comment
end

def test_constant_decl_2
parser = parser(<<~RBS)
class A
# Constant comment test
CONSTANT: ("Literal" | "Union check")
end
RBS

parser.scan()

top_level = parser.top_level

klass = top_level.find_class_or_module("A")
constant = klass.constants.first

assert_instance_of RDoc::Constant, constant
assert_equal "CONSTANT", constant.name
assert_equal "\"Literal\" | \"Union check\"", constant.value
assert_equal "Constant comment test", constant.comment.text
end

def test_method_alias_decl_1
parser = parser(<<~RBS)
class A
def foo: () -> void
alias bar foo
end
RBS

parser.scan()

top_level = parser.top_level

klass = top_level.find_class_or_module("A")
method = klass.method_list.find { |m| m.name == "bar" }

assert_instance_of RDoc::AnyMethod, method
assert_equal "bar", method.name
assert_instance_of RDoc::AnyMethod, method.is_alias_for
assert_equal "foo", method.is_alias_for.name
assert_nil method.is_alias_for.is_alias_for
end

def test_method_alias_decl_2
parser = parser(<<~RBS)
class A
def foo: () -> void
alias bar foo
alias baz bar
alias foo dam
end
RBS

parser.scan()

top_level = parser.top_level

klass = top_level.find_class_or_module("A")
method = klass.method_list.find { |m| m.name == "baz" }

assert_instance_of RDoc::AnyMethod, method
assert_equal "baz", method.name
assert_instance_of RDoc::AnyMethod, method.is_alias_for
assert_equal "bar", method.is_alias_for.name
assert_instance_of RDoc::AnyMethod, method.is_alias_for.is_alias_for
assert_equal "foo", method.is_alias_for.is_alias_for.name

assert_instance_of RDoc::Alias, klass.external_aliases.first
assert_equal "foo", klass.external_aliases.first.name
assert_equal "dam", klass.external_aliases.first.old_name
end

def test_attr_decl_1
parser = parser(<<~RBS)
class A
attr_reader foo: Integer
attr_writer bar: Float
attr_accessor dam: String
end
RBS

parser.scan()

top_level = parser.top_level

klass = top_level.find_class_or_module("A")
attr_r = klass.attributes[0]
attr_w = klass.attributes[1]
attr_a = klass.attributes[2]

assert_instance_of RDoc::Attr, attr_r
assert_equal "foo", attr_r.name
assert_equal "R", attr_r.rw
assert_equal "", attr_r.comment

assert_instance_of RDoc::Attr, attr_w
assert_equal "bar", attr_w.name
assert_equal "W", attr_w.rw
assert_equal "", attr_w.comment

assert_instance_of RDoc::Attr, attr_a
assert_equal "dam", attr_a.name
assert_equal "RW", attr_a.rw
assert_equal "", attr_a.comment
end

def test_attr_decl_2
parser = parser(<<~RBS)
class A
# Comment 1
attr_reader foo: Integer
# Comment 2
attr_writer bar: Float
# Comment 3
attr_accessor dam: String
end
RBS

parser.scan()

top_level = parser.top_level

klass = top_level.find_class_or_module("A")
attr_r = klass.attributes[0]
attr_w = klass.attributes[1]
attr_a = klass.attributes[2]

assert_instance_of RDoc::Attr, attr_r
assert_equal "foo", attr_r.name
assert_equal "R", attr_r.rw
assert_equal "Comment 1", attr_r.comment.text

assert_instance_of RDoc::Attr, attr_w
assert_equal "bar", attr_w.name
assert_equal "W", attr_w.rw
assert_equal "Comment 2", attr_w.comment.text

assert_instance_of RDoc::Attr, attr_a
assert_equal "dam", attr_a.name
assert_equal "RW", attr_a.rw
assert_equal "Comment 3", attr_a.comment.text
end

def test_include_decl_1
parser = parser(<<~RBS)
module D
end
class A
module B
end
class C
include B
# Test comment
include D
end
end
RBS

parser.scan()

top_level = parser.top_level

klass = top_level.find_class_or_module("A::C")
rdoc_include = klass.includes.first
assert_instance_of RDoc::Include, rdoc_include
assert_equal "A::B", rdoc_include.name
assert_equal "", rdoc_include.comment

rdoc_include = klass.includes[1]
assert_instance_of RDoc::Include, rdoc_include
assert_equal "D", rdoc_include.name
assert_equal "Test comment", rdoc_include.comment.text
end

def test_extend_decl_1
parser = parser(<<~RBS)
module D
end
class A
module B
end
class C
extend B
# Test comment
extend D
end
end
RBS

parser.scan()

top_level = parser.top_level

klass = top_level.find_class_or_module("A::C")
rdoc_extend = klass.extends.first
assert_instance_of RDoc::Extend, rdoc_extend
assert_equal "A::B", rdoc_extend.name
assert_equal "", rdoc_extend.comment

rdoc_extend = klass.extends[1]
assert_instance_of RDoc::Extend, rdoc_extend
assert_equal "D", rdoc_extend.name
assert_equal "Test comment", rdoc_extend.comment.text
end
end

0 comments on commit 5a56646

Please sign in to comment.