rbs 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (132) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ruby.yml +28 -0
  3. data/.gitignore +12 -0
  4. data/.rubocop.yml +15 -0
  5. data/BSDL +22 -0
  6. data/CHANGELOG.md +9 -0
  7. data/COPYING +56 -0
  8. data/Gemfile +6 -0
  9. data/README.md +93 -0
  10. data/Rakefile +142 -0
  11. data/bin/annotate-with-rdoc +157 -0
  12. data/bin/console +14 -0
  13. data/bin/query-rdoc +103 -0
  14. data/bin/setup +10 -0
  15. data/bin/sort +89 -0
  16. data/bin/test_runner.rb +16 -0
  17. data/docs/CONTRIBUTING.md +97 -0
  18. data/docs/sigs.md +148 -0
  19. data/docs/stdlib.md +152 -0
  20. data/docs/syntax.md +528 -0
  21. data/exe/rbs +7 -0
  22. data/lib/rbs.rb +64 -0
  23. data/lib/rbs/ast/annotation.rb +27 -0
  24. data/lib/rbs/ast/comment.rb +27 -0
  25. data/lib/rbs/ast/declarations.rb +395 -0
  26. data/lib/rbs/ast/members.rb +362 -0
  27. data/lib/rbs/buffer.rb +50 -0
  28. data/lib/rbs/builtin_names.rb +55 -0
  29. data/lib/rbs/cli.rb +558 -0
  30. data/lib/rbs/constant.rb +26 -0
  31. data/lib/rbs/constant_table.rb +150 -0
  32. data/lib/rbs/definition.rb +170 -0
  33. data/lib/rbs/definition_builder.rb +919 -0
  34. data/lib/rbs/environment.rb +281 -0
  35. data/lib/rbs/environment_loader.rb +136 -0
  36. data/lib/rbs/environment_walker.rb +124 -0
  37. data/lib/rbs/errors.rb +187 -0
  38. data/lib/rbs/location.rb +102 -0
  39. data/lib/rbs/method_type.rb +123 -0
  40. data/lib/rbs/namespace.rb +91 -0
  41. data/lib/rbs/parser.y +1344 -0
  42. data/lib/rbs/prototype/rb.rb +553 -0
  43. data/lib/rbs/prototype/rbi.rb +587 -0
  44. data/lib/rbs/prototype/runtime.rb +381 -0
  45. data/lib/rbs/substitution.rb +46 -0
  46. data/lib/rbs/test.rb +26 -0
  47. data/lib/rbs/test/errors.rb +61 -0
  48. data/lib/rbs/test/hook.rb +294 -0
  49. data/lib/rbs/test/setup.rb +58 -0
  50. data/lib/rbs/test/spy.rb +325 -0
  51. data/lib/rbs/test/test_helper.rb +183 -0
  52. data/lib/rbs/test/type_check.rb +254 -0
  53. data/lib/rbs/type_name.rb +70 -0
  54. data/lib/rbs/types.rb +936 -0
  55. data/lib/rbs/variance_calculator.rb +138 -0
  56. data/lib/rbs/vendorer.rb +47 -0
  57. data/lib/rbs/version.rb +3 -0
  58. data/lib/rbs/writer.rb +269 -0
  59. data/lib/ruby/signature.rb +7 -0
  60. data/rbs.gemspec +46 -0
  61. data/stdlib/abbrev/abbrev.rbs +60 -0
  62. data/stdlib/base64/base64.rbs +71 -0
  63. data/stdlib/benchmark/benchmark.rbs +372 -0
  64. data/stdlib/builtin/array.rbs +1997 -0
  65. data/stdlib/builtin/basic_object.rbs +280 -0
  66. data/stdlib/builtin/binding.rbs +177 -0
  67. data/stdlib/builtin/builtin.rbs +45 -0
  68. data/stdlib/builtin/class.rbs +145 -0
  69. data/stdlib/builtin/comparable.rbs +116 -0
  70. data/stdlib/builtin/complex.rbs +400 -0
  71. data/stdlib/builtin/constants.rbs +37 -0
  72. data/stdlib/builtin/data.rbs +5 -0
  73. data/stdlib/builtin/deprecated.rbs +2 -0
  74. data/stdlib/builtin/dir.rbs +413 -0
  75. data/stdlib/builtin/encoding.rbs +607 -0
  76. data/stdlib/builtin/enumerable.rbs +404 -0
  77. data/stdlib/builtin/enumerator.rbs +260 -0
  78. data/stdlib/builtin/errno.rbs +781 -0
  79. data/stdlib/builtin/errors.rbs +582 -0
  80. data/stdlib/builtin/exception.rbs +194 -0
  81. data/stdlib/builtin/false_class.rbs +40 -0
  82. data/stdlib/builtin/fiber.rbs +68 -0
  83. data/stdlib/builtin/fiber_error.rbs +12 -0
  84. data/stdlib/builtin/file.rbs +1076 -0
  85. data/stdlib/builtin/file_test.rbs +59 -0
  86. data/stdlib/builtin/float.rbs +696 -0
  87. data/stdlib/builtin/gc.rbs +243 -0
  88. data/stdlib/builtin/hash.rbs +1029 -0
  89. data/stdlib/builtin/integer.rbs +707 -0
  90. data/stdlib/builtin/io.rbs +683 -0
  91. data/stdlib/builtin/kernel.rbs +576 -0
  92. data/stdlib/builtin/marshal.rbs +161 -0
  93. data/stdlib/builtin/match_data.rbs +271 -0
  94. data/stdlib/builtin/math.rbs +369 -0
  95. data/stdlib/builtin/method.rbs +185 -0
  96. data/stdlib/builtin/module.rbs +1104 -0
  97. data/stdlib/builtin/nil_class.rbs +82 -0
  98. data/stdlib/builtin/numeric.rbs +409 -0
  99. data/stdlib/builtin/object.rbs +824 -0
  100. data/stdlib/builtin/proc.rbs +429 -0
  101. data/stdlib/builtin/process.rbs +1227 -0
  102. data/stdlib/builtin/random.rbs +267 -0
  103. data/stdlib/builtin/range.rbs +226 -0
  104. data/stdlib/builtin/rational.rbs +424 -0
  105. data/stdlib/builtin/rb_config.rbs +57 -0
  106. data/stdlib/builtin/regexp.rbs +1083 -0
  107. data/stdlib/builtin/ruby_vm.rbs +14 -0
  108. data/stdlib/builtin/signal.rbs +55 -0
  109. data/stdlib/builtin/string.rbs +1901 -0
  110. data/stdlib/builtin/string_io.rbs +284 -0
  111. data/stdlib/builtin/struct.rbs +40 -0
  112. data/stdlib/builtin/symbol.rbs +228 -0
  113. data/stdlib/builtin/thread.rbs +1108 -0
  114. data/stdlib/builtin/thread_group.rbs +23 -0
  115. data/stdlib/builtin/time.rbs +1047 -0
  116. data/stdlib/builtin/trace_point.rbs +290 -0
  117. data/stdlib/builtin/true_class.rbs +46 -0
  118. data/stdlib/builtin/unbound_method.rbs +153 -0
  119. data/stdlib/builtin/warning.rbs +17 -0
  120. data/stdlib/coverage/coverage.rbs +62 -0
  121. data/stdlib/csv/csv.rbs +773 -0
  122. data/stdlib/erb/erb.rbs +392 -0
  123. data/stdlib/find/find.rbs +40 -0
  124. data/stdlib/ipaddr/ipaddr.rbs +247 -0
  125. data/stdlib/json/json.rbs +335 -0
  126. data/stdlib/pathname/pathname.rbs +1093 -0
  127. data/stdlib/prime/integer-extension.rbs +23 -0
  128. data/stdlib/prime/prime.rbs +188 -0
  129. data/stdlib/securerandom/securerandom.rbs +9 -0
  130. data/stdlib/set/set.rbs +301 -0
  131. data/stdlib/tmpdir/tmpdir.rbs +53 -0
  132. metadata +292 -0
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "rbs"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "rdoc"
4
+
5
+ def store_for_class(name, stores:)
6
+ stores.find do |store|
7
+ store.find_class_named(name) || store.find_module_named(name)
8
+ end
9
+ end
10
+
11
+ def format_comment(comment)
12
+ out = RDoc::Markup::Document.new
13
+ out << comment
14
+ formatter = RDoc::Markup::ToMarkdown.new
15
+ out.accept(formatter)
16
+ end
17
+
18
+ def comment_for_constant(name, stores:)
19
+ *class_components, const_name = name.split(/::/)
20
+ class_name = class_components.join("::")
21
+
22
+ klass = store_for_class(class_name, stores: stores)&.yield_self {|store|
23
+ store.find_class_named(class_name) || store.find_module_named(class_name)
24
+ }
25
+
26
+ constant = klass.constants.find do |const|
27
+ const.name == const_name
28
+ end
29
+
30
+ if constant&.documented?
31
+ format_comment(constant.comment)
32
+ end
33
+ end
34
+
35
+ def comment_for_class(class_name, stores:)
36
+ klass = store_for_class(class_name, stores: stores)&.yield_self {|store|
37
+ store.find_class_named(class_name) || store.find_module_named(class_name)
38
+ }
39
+
40
+ if klass&.documented?
41
+ format_comment(klass.comment)
42
+ end
43
+ end
44
+
45
+ def comment_for_method(klass, method, stores:)
46
+ method = store_for_class(klass, stores: stores)&.load_method(klass, method)
47
+
48
+ if method&.documented?
49
+ out = RDoc::Markup::Document.new
50
+
51
+ out << method.comment
52
+
53
+ if method.arglists
54
+ out << RDoc::Markup::Heading.new(1, "arglists 💪👽🚨 << Delete this section")
55
+ arglists = method.arglists.chomp.split("\n").map {|line| line + "\n" }
56
+ out << RDoc::Markup::Verbatim.new(*arglists)
57
+ end
58
+
59
+ out.accept(RDoc::Markup::ToMarkdown.new)
60
+ end
61
+ rescue RDoc::Store::MissingFileError
62
+ nil
63
+ end
64
+
65
+ if ARGV.empty?
66
+ puts 'query-rdoc [subject]'
67
+ puts " subject ::= ClassName (class, module, or constant)"
68
+ puts " | ClassName.method (singleton method)"
69
+ puts " | ClassName#method (instance method)"
70
+ exit
71
+ end
72
+
73
+ stores = []
74
+ RDoc::RI::Paths.each true, true, false, false do |path, type|
75
+ STDERR.puts "Loading store from #{path}..."
76
+ store = RDoc::RI::Store.new(path, type)
77
+ store.load_all
78
+ stores << store
79
+ end
80
+
81
+ subject = ARGV[0]
82
+
83
+ case
84
+ when match = subject.match(/(?<constant_name>[^#]+)#(?<method_name>.+)/)
85
+ STDERR.puts "Finding instance method #{match[:constant_name]} # #{match[:method_name]} ..."
86
+ comment = comment_for_method(match[:constant_name], "##{match[:method_name]}", stores: stores)
87
+ when match = subject.match(/(?<constant_name>[^.]+)\.(?<method_name>.+)/)
88
+ STDERR.puts "Finding singleton method #{match[:constant_name]} . #{match[:method_name]} ..."
89
+ comment = comment_for_method(match[:constant_name], "::#{match[:method_name]}", stores: stores)
90
+ else
91
+ STDERR.puts "Finding class/module/constant #{subject} ..."
92
+ comment = comment_for_class(subject, stores: stores) || comment_for_constant(subject, stores: stores)
93
+ end
94
+
95
+ if comment
96
+ STDERR.puts "Printing document..."
97
+ comment.each_line do |line|
98
+ puts "# #{line}"
99
+ end
100
+ else
101
+ STDERR.puts "Nothing to print; failed to query the document..."
102
+ exit 1
103
+ end
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install --jobs 4 --retry 3
7
+
8
+ # Do any other automated setup that you need to do here
9
+
10
+ bundle exec rake parser
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "rbs"
5
+
6
+ Members = RBS::AST::Members
7
+
8
+ def group(member)
9
+ case member
10
+ when Members::Include, Members::Extend, Members::Prepend
11
+ 0
12
+ when Members::ClassVariable
13
+ -3
14
+ when Members::ClassInstanceVariable
15
+ -2
16
+ when Members::InstanceVariable
17
+ -1
18
+ when Members::AttrAccessor, Members::AttrWriter, Members::AttrReader
19
+ 2
20
+ when Members::MethodDefinition
21
+ if member.singleton?
22
+ if member.name == :new
23
+ 0.4
24
+ else
25
+ 1
26
+ end
27
+ else
28
+ if member.name == :initialize
29
+ 0.5
30
+ else
31
+ 3
32
+ end
33
+ end
34
+ when Members::Alias
35
+ if member.singleton?
36
+ 1
37
+ else
38
+ 3
39
+ end
40
+ when Members::Private, Members::Public
41
+ -4
42
+ end
43
+ end
44
+
45
+ def key(member)
46
+ case member
47
+ when Members::Include, Members::Extend, Members::Prepend
48
+ member.name.to_s
49
+ when Members::ClassVariable, Members::ClassInstanceVariable, Members::InstanceVariable
50
+ member.name.to_s
51
+ when Members::AttrAccessor, Members::AttrWriter, Members::AttrReader
52
+ member.name.to_s
53
+ when Members::MethodDefinition
54
+ member.name.to_s
55
+ when Members::Alias
56
+ member.new_name.to_s
57
+ else
58
+ 1
59
+ end
60
+ end
61
+
62
+ ARGV.map {|f| Pathname(f) }.each do |path|
63
+ puts "Opening #{path}..."
64
+
65
+ buffer = RBS::Buffer.new(name: path, content: path.read)
66
+ sigs = RBS::Parser.parse_signature(buffer)
67
+
68
+ sigs.each do |sig|
69
+ case sig
70
+ when RBS::AST::Declarations::Class, RBS::AST::Declarations::Module, RBS::AST::Declarations::Interface
71
+ sig.members.sort! do |m1, m2|
72
+ group1 = group(m1)
73
+ group2 = group(m2)
74
+
75
+ if group1 == group2
76
+ key(m1) <=> key(m2)
77
+ else
78
+ group1 <=> group2
79
+ end
80
+ end
81
+ end
82
+ end
83
+
84
+ puts "Writing #{path}..."
85
+ path.open('w') do |out|
86
+ writer = RBS::Writer.new(out: out)
87
+ writer.write sigs
88
+ end
89
+ end
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ RUBY_27 = Gem::Version.new(RUBY_VERSION).yield_self do |ruby_version|
4
+ Gem::Version.new('2.7.0') <= ruby_version && ruby_version < Gem::Version.new("2.8.0")
5
+ end
6
+
7
+ unless RUBY_27
8
+ STDERR.puts "🚨🚨🚨 stdlib test requires Ruby 2.7 but RUBY_VERSION==#{RUBY_VERSION}, exiting... 🚨🚨🚨"
9
+ exit
10
+ end
11
+
12
+ require "pathname"
13
+
14
+ ARGV.each do |arg|
15
+ load arg
16
+ end
@@ -0,0 +1,97 @@
1
+ # Standard Library Signatures Contribution Guide
2
+
3
+ ## Guides
4
+
5
+ * [Stdlib Signatures Guide](stdlib.md)
6
+ * [Syntax](syntax.md)
7
+ * [Writing Signature Guide](sigs.md)
8
+
9
+ ## Steps for Contribution
10
+
11
+ 1. Pick the class/library you will work for.
12
+ 2. Assign yourself on the [work spreadsheet](https://docs.google.com/spreadsheets/d/199rRB93I16H0k4TGZS3EGojns2R0W1oCsN8UPJzOpyU/edit#gid=1383307992) (optional but recommended to avoid duplication).
13
+ 3. Sort RBS members (if there is RBS files for the classes).
14
+ - Use `bin/sort stdlib/path/to/signature.rbs` command and confirm it does not break definitions.
15
+ - Committing the sorted RBSs is recommended.
16
+ 4. Add method prototypes.
17
+ - Use `rbs prototype runtime --merge CLASS_NAME` command to generate the missing method definitions.
18
+ - Committing the auto generated signatures is recommended.
19
+ 5. Annotate with RDoc.
20
+ - Use `bin/annotate-with-rdoc stdlib/path/to/signature.rbs` to annotate the RBS files.
21
+ - Committing the generated annotations is recommended.
22
+ 6. Fix method types and comments.
23
+ - The auto generated RDoc comments include `arglists` section, which we don't expect to be included the RBS files.
24
+ - Delete the `arglists` sections.
25
+ - Give methods correct types.
26
+ - Write tests, if possible. (If it is too difficult to write test, skip it.)
27
+
28
+ ## The Target Version
29
+
30
+ * The standard library signatures targets Ruby 2.7 for now.
31
+ * The library code targets Ruby 2.6, 2.7, and 3.0.
32
+
33
+ ## Stdlib Worksheet
34
+
35
+ You can find the list of classes/libraries:
36
+
37
+ * https://docs.google.com/spreadsheets/d/199rRB93I16H0k4TGZS3EGojns2R0W1oCsN8UPJzOpyU/edit#gid=1383307992
38
+
39
+ Assign yourself when you start working for a class or library.
40
+ After reviewing and merging your pull request, I will update the status of the library.
41
+
42
+ You may find the *Good for first contributor* column where you can find some classes are recommended for new contributors (👍), and some classes are not-recommended (👎).
43
+
44
+ ## Useful Tools
45
+
46
+ * `rbs prototype runtime --merge String`
47
+ * Generate a prototype using runtime API.
48
+ * `--merge` tells to use the method types in RBS if exists.
49
+ * `rbs prototype runtime --merge --method-owner=Numeric Integer`
50
+ * You can use --method-owner if you want to print method of other classes too, for documentation purpose.
51
+ * `bin/annotate-with-rdoc stdlib/builtin/string.rbs`
52
+ * Write comments using RDoc.
53
+ * It contains arglists section, but I don't think we should have it in RBS files.
54
+ * `bin/query-rdoc String#initialize`
55
+ * Print RDoc documents in the format you can copy-and-paste to RBS.
56
+ * `bin/sort stdlib/builtin/string.rbs`
57
+ * Sort declarations members in RBS files.
58
+ * `rbs validate -r LIB`
59
+ Validate the syntax and some of the semantics.
60
+ * `rake generate:stdlib_test[String]`
61
+ Scaffold the stdlib test.
62
+
63
+ ## Standard STDLIB Members Order
64
+
65
+ We define the standard members order so that ordering doesn't bother reading diffs or git-annotate outputs.
66
+
67
+ 1. `def self.new` or `def initialize`
68
+ 2. Mixins
69
+ 3. Attributes
70
+ 4. Singleton methods
71
+ 5. `public` & public instance methods
72
+ 6. `private` & private instance methods
73
+
74
+ ```
75
+ class HelloWorld[X]
76
+ def self.new: [A] () { (void) -> A } -> HelloWorld[A] # new or initialize comes first
77
+ def initialize: () -> void
78
+
79
+ include Enumerable[X, void] # Mixin comes next
80
+
81
+ attr_reader language: (:ja | :en) # Attributes
82
+
83
+ def self.all_languages: () -> Array[Symbol] # Singleton methods
84
+
85
+ public # Public instance methods
86
+
87
+ def each: () { (A) -> void } -> void # Members are sorted dicionary order
88
+
89
+ def to_s: (?Locale) -> String
90
+
91
+ private # Private instance methods
92
+
93
+ alias validate validate_locale
94
+
95
+ def validate_locale: () -> void
96
+ end
97
+ ```
@@ -0,0 +1,148 @@
1
+ # Writing Signatures Guide
2
+
3
+ You can write the signature of your applications and libraries.
4
+ Signature of your Ruby program would help:
5
+
6
+ 1. Understanding the code structure
7
+ 2. Finding APIs
8
+
9
+ And if you ship your gem with signature, the gem users can type check their applications!
10
+
11
+ ## Writing signatures
12
+
13
+ You first need to write your program's signature.
14
+ See [syntax guide](syntax.md).
15
+
16
+ ## Testing signatures
17
+
18
+ When you finish writing signature, you may want to test the signature.
19
+ ruby-signature provides a feature to test your signature.
20
+
21
+ ```
22
+ $ RBS_TEST_TARGET='Foo::*' bundle exec ruby -r rbs/test/setup test/foo_test.rb
23
+ ```
24
+
25
+ The test installs instrumentations to spy the method calls and check if arguments/return values are correct with respect to the type of the method in signature.
26
+ If errors are reported by the test, you will fix the signature.
27
+ You will be sure that you ship a correct signature finally.
28
+
29
+ The instrumentations are implemneted using `Module#prepend`.
30
+ It defines a module with same name of methods, which asserts the type of arguments/return values and calls `super`.
31
+
32
+ ## Type errors
33
+
34
+ If the test detects type errors, it will print error messages.
35
+
36
+ ### ArgumentTypeError, BlockArgumentTypeError
37
+
38
+ The message means there is an unexpected type of argument or block argument.
39
+
40
+ ```
41
+ ERROR -- : [Kaigi::Speaker.new] ArgumentTypeError: expected `::String` (email) but given `:"matsumoto@soutaro.com"`
42
+ ```
43
+
44
+ ### ArgumentError, BlockArgumentError
45
+
46
+ The message means there is an unexpected argument or missing argument.
47
+
48
+ ```
49
+ [Kaigi::Speaker.new] ArgumentError: expected method type (size: ::Symbol, email: ::String, name: ::String) -> ::Kaigi::Speaker
50
+ ```
51
+
52
+ ### ReturnTypeError, BlockReturnTypeError
53
+
54
+ The message means the return value from method or block is incorrect.
55
+
56
+ ```
57
+ ERROR -- : [Kaigi::Conference#each_speaker] ReturnTypeError: expected `self` but returns `[#<Kaigi::Speaker:0x00007fb2b249e5a0 @name="Soutaro Matsumoto", @email=:"matsumoto@soutaro.com">]`
58
+ ```
59
+
60
+ ### UnexpectedBlockError, MissingBlockError
61
+
62
+ The errors are reported when required block is not given or unused block is given.
63
+
64
+ ```
65
+ ERROR -- : [Kaigi::Conference#speakers] UnexpectedBlockError: unexpected block is given for `() -> ::Array[::Kaigi::Speaker]`
66
+ ```
67
+
68
+ ### UnresolvedOverloadingError
69
+
70
+ The error means there is a type error on overloaded methods.
71
+ The `ruby-signature` test framework tries to the best error message for overloaded methods too, but it reports the `UnresolvedOverloadingError` when it fails.
72
+
73
+ ## Setting up the test
74
+
75
+ The design of the signature testing aims to be non-intrusive. The setup is done in two steps:
76
+
77
+ 1. Loading the testing library
78
+ 2. Setting up the test through environment variables
79
+
80
+ ### Loading the library
81
+
82
+ You need to require `rbs/test/setup` for signature testing.
83
+ You can do it using `-r` option through command line argument or the `RUBYOPT` environment variable.
84
+
85
+ ```
86
+ $ ruby -r rbs/test/setup run_tests.rb
87
+ $ RUBYOPT='-rruby/signature/test/setup' rake test
88
+ ```
89
+
90
+ When you are using Bundler, you may need to require `bundler/setup` explicitly.
91
+
92
+ ```
93
+ $ RUBYOPT='-rbundler/setup -rruby/signature/test/setup' bundle exec rake test
94
+ ```
95
+
96
+ ### Environment variables
97
+
98
+ You need to specify `RBS_TEST_TARGET` to run the test, and you can customize the test with the following environment variables.
99
+
100
+ - `RBS_TEST_SKIP` (optional)
101
+ - `RBS_TEST_OPT` (optional)
102
+ - `RBS_TEST_LOGLEVEL` (optional)
103
+ - `RBS_TEST_RAISE` (optional)
104
+
105
+ `RBS_TEST_TARGET` is to specify the classes you want to test. `RBS_TEST_TARGET` can contain comma-separated class name pattern, which is one of an exact class name or with wildcard `*`.
106
+
107
+ - `RBS_TEST_TARGET=Foo::Bar,Foo::Baz` comma separated exact class names
108
+ - `RBS_TEST_TARGET=Foo::*` using wildcard
109
+
110
+ `RBS_TEST_SKIP` is to skip some of the classes which matches with `RBS_TEST_TARGET`.
111
+
112
+ `RBS_TEST_OPT` is to pass the options for ruby signature handling.
113
+ You may need to specify `-r` or `-I` to load signatures.
114
+ The default is `-I sig`.
115
+
116
+ ```
117
+ RBS_TEST_OPT='-r set -r pathname -I sig'
118
+ ```
119
+
120
+ `RBS_TEST_LOGLEVEL` can be used to configure log level. Defaults to `info`.
121
+
122
+ `RBS_TEST_RAISE` may help to debug the type signatures.
123
+ If the environment variable is set, it raises an exception when a type error is detected.
124
+ You can see the backtrace how the type error is caused and debug your program or signature.
125
+
126
+ So, a typical command line to start the test would look like the following:
127
+
128
+ ```
129
+ $ RBS_TEST_LOGLEVEL=error \
130
+ RBS_TEST_TARGET='Kaigi::*' \
131
+ RBS_TEST_SKIP='Kaigi::MonkeyPatch' \
132
+ RBS_TEST_OPT='-rset -rpathname -Isig -Iprivate' \
133
+ RBS_TEST_RAISE=true \
134
+ RUBYOPT='-rbundler/setup -rruby/signature/test/setup' \
135
+ bundle exec rake test
136
+ ```
137
+
138
+ ## Testing tips
139
+
140
+ ### Skipping a method
141
+
142
+ You can skip installing the instrumentation per-method basis using `rbs:test:skip` annotation.
143
+
144
+ ```
145
+ class String
146
+ %a{rbs:test:skip} def =~: (Regexp) -> Integer?
147
+ end
148
+ ```