@@ -943,4 +943,181 @@ class Foo
943943 end
944944 end
945945 end
946+
947+ def test_parse__class_with_super_class
948+ result = parse ( <<~RUBY )
949+ class Child < Parent
950+ end
951+ RUBY
952+
953+ assert_empty result . diagnostics
954+
955+ result . declarations [ 0 ] . tap do |decl |
956+ assert_instance_of RBS ::AST ::Ruby ::Declarations ::ClassDecl , decl
957+ assert_equal RBS ::TypeName . parse ( "Child" ) , decl . class_name
958+ assert_instance_of RBS ::AST ::Ruby ::Declarations ::ClassDecl ::SuperClass , decl . super_class
959+ assert_equal RBS ::TypeName . parse ( "Parent" ) , decl . super_class . name
960+ assert_empty decl . super_class . args
961+ end
962+ end
963+
964+ def test_parse__class_with_super_class_nested
965+ result = parse ( <<~RUBY )
966+ class UsersController < ApplicationController
967+ class Error < StandardError
968+ end
969+ end
970+ RUBY
971+
972+ assert_empty result . diagnostics
973+
974+ result . declarations [ 0 ] . tap do |decl |
975+ assert_instance_of RBS ::AST ::Ruby ::Declarations ::ClassDecl , decl
976+ assert_equal RBS ::TypeName . parse ( "UsersController" ) , decl . class_name
977+ assert_instance_of RBS ::AST ::Ruby ::Declarations ::ClassDecl ::SuperClass , decl . super_class
978+ assert_equal RBS ::TypeName . parse ( "ApplicationController" ) , decl . super_class . name
979+ assert_empty decl . super_class . args
980+
981+ decl . members [ 0 ] . tap do |member |
982+ assert_instance_of RBS ::AST ::Ruby ::Declarations ::ClassDecl , member
983+ assert_equal RBS ::TypeName . parse ( "Error" ) , member . class_name
984+ assert_instance_of RBS ::AST ::Ruby ::Declarations ::ClassDecl ::SuperClass , member . super_class
985+ assert_equal RBS ::TypeName . parse ( "StandardError" ) , member . super_class . name
986+ assert_empty member . super_class . args
987+ end
988+ end
989+ end
990+
991+ def test_parse__class_with_super_class_type_application
992+ result = parse ( <<~RUBY )
993+ class StringArray < Array #[String]
994+ end
995+ RUBY
996+
997+ assert_empty result . diagnostics
998+
999+ result . declarations [ 0 ] . tap do |decl |
1000+ assert_instance_of RBS ::AST ::Ruby ::Declarations ::ClassDecl , decl
1001+ assert_equal RBS ::TypeName . parse ( "StringArray" ) , decl . class_name
1002+ assert_instance_of RBS ::AST ::Ruby ::Declarations ::ClassDecl ::SuperClass , decl . super_class
1003+ assert_equal RBS ::TypeName . parse ( "Array" ) , decl . super_class . name
1004+ assert_equal 1 , decl . super_class . args . size
1005+ assert_equal "String" , decl . super_class . args [ 0 ] . to_s
1006+ end
1007+ end
1008+
1009+ def test_parse__class_with_super_class_complex_type_application
1010+ result = parse ( <<~RUBY )
1011+ class MyHash < Hash #[Symbol, Array[Integer]]
1012+ end
1013+ RUBY
1014+
1015+ assert_empty result . diagnostics
1016+
1017+ result . declarations [ 0 ] . tap do |decl |
1018+ assert_instance_of RBS ::AST ::Ruby ::Declarations ::ClassDecl , decl
1019+ assert_equal RBS ::TypeName . parse ( "MyHash" ) , decl . class_name
1020+ assert_instance_of RBS ::AST ::Ruby ::Declarations ::ClassDecl ::SuperClass , decl . super_class
1021+ assert_equal RBS ::TypeName . parse ( "Hash" ) , decl . super_class . name
1022+ assert_equal 2 , decl . super_class . args . size
1023+ assert_equal "Symbol" , decl . super_class . args [ 0 ] . to_s
1024+ assert_equal "Array[Integer]" , decl . super_class . args [ 1 ] . to_s
1025+ end
1026+ end
1027+
1028+ def test_parse__class_with_qualified_super_class
1029+ result = parse ( <<~RUBY )
1030+ class MyError < ActiveRecord::RecordNotFound
1031+ end
1032+ RUBY
1033+
1034+ assert_empty result . diagnostics
1035+
1036+ result . declarations [ 0 ] . tap do |decl |
1037+ assert_instance_of RBS ::AST ::Ruby ::Declarations ::ClassDecl , decl
1038+ assert_equal RBS ::TypeName . parse ( "MyError" ) , decl . class_name
1039+ assert_instance_of RBS ::AST ::Ruby ::Declarations ::ClassDecl ::SuperClass , decl . super_class
1040+ assert_equal RBS ::TypeName . parse ( "ActiveRecord::RecordNotFound" ) , decl . super_class . name
1041+ assert_empty decl . super_class . args
1042+ end
1043+ end
1044+
1045+ def test_error__class_with_non_constant_super_class
1046+ result = parse ( <<~RUBY )
1047+ class Child < parent
1048+ end
1049+ RUBY
1050+
1051+ assert_equal 1 , result . diagnostics . size
1052+ assert_any! ( result . diagnostics ) do |diagnostic |
1053+ assert_instance_of RBS ::InlineParser ::Diagnostic ::NonConstantSuperClassName , diagnostic
1054+ assert_equal "parent" , diagnostic . location . source
1055+ assert_equal "Super class name must be a constant" , diagnostic . message
1056+ end
1057+
1058+ # The class should still be created but without super class
1059+ result . declarations [ 0 ] . tap do |decl |
1060+ assert_instance_of RBS ::AST ::Ruby ::Declarations ::ClassDecl , decl
1061+ assert_equal RBS ::TypeName . parse ( "Child" ) , decl . class_name
1062+ assert_nil decl . super_class
1063+ end
1064+ end
1065+
1066+ def test_error__class_with_dynamic_super_class
1067+ result = parse ( <<~RUBY )
1068+ Parent = Class.new
1069+ class Child < Parent.new
1070+ end
1071+ RUBY
1072+
1073+ assert_equal 1 , result . diagnostics . size
1074+ assert_any! ( result . diagnostics ) do |diagnostic |
1075+ assert_instance_of RBS ::InlineParser ::Diagnostic ::NonConstantSuperClassName , diagnostic
1076+ assert_equal "Parent.new" , diagnostic . location . source
1077+ assert_equal "Super class name must be a constant" , diagnostic . message
1078+ end
1079+
1080+ # The class should still be created but without super class
1081+ result . declarations [ 0 ] . tap do |decl |
1082+ assert_instance_of RBS ::AST ::Ruby ::Declarations ::ClassDecl , decl
1083+ assert_equal RBS ::TypeName . parse ( "Child" ) , decl . class_name
1084+ assert_nil decl . super_class
1085+ end
1086+ end
1087+
1088+ def test_parse__class_with_super_class_and_members
1089+ result = parse ( <<~RUBY )
1090+ class Person < ActiveRecord::Base #[Person]
1091+ attr_reader :name #: String
1092+
1093+ def age
1094+ 25
1095+ end
1096+ end
1097+ RUBY
1098+
1099+ assert_empty result . diagnostics
1100+
1101+ result . declarations [ 0 ] . tap do |decl |
1102+ assert_instance_of RBS ::AST ::Ruby ::Declarations ::ClassDecl , decl
1103+ assert_equal RBS ::TypeName . parse ( "Person" ) , decl . class_name
1104+ assert_instance_of RBS ::AST ::Ruby ::Declarations ::ClassDecl ::SuperClass , decl . super_class
1105+ assert_equal RBS ::TypeName . parse ( "ActiveRecord::Base" ) , decl . super_class . name
1106+ assert_equal 1 , decl . super_class . args . size
1107+ assert_equal "Person" , decl . super_class . args [ 0 ] . to_s
1108+
1109+ assert_equal 2 , decl . members . size
1110+
1111+ decl . members [ 0 ] . tap do |member |
1112+ assert_instance_of RBS ::AST ::Ruby ::Members ::AttrReaderMember , member
1113+ assert_equal [ :name ] , member . names
1114+ assert_equal "String" , member . type . to_s
1115+ end
1116+
1117+ decl . members [ 1 ] . tap do |member |
1118+ assert_instance_of RBS ::AST ::Ruby ::Members ::DefMember , member
1119+ assert_equal :age , member . name
1120+ end
1121+ end
1122+ end
9461123end
0 commit comments