module RBS::UnitTest::TypeAssertions
Public Class Methods
included(base)
click to toggle source
# File rbs-3.6.1/lib/rbs/unit_test/type_assertions.rb, line 57 def self.included(base) base.extend ClassMethods end
Public Instance Methods
allow_non_simple_method_type() { || ... }
click to toggle source
# File rbs-3.6.1/lib/rbs/unit_test/type_assertions.rb, line 314 def allow_non_simple_method_type() begin @allows_non_simple_method_type = true yield rescue @allows_non_simple_method_type = false end end
allows_error(*errors) { || ... }
click to toggle source
# File rbs-3.6.1/lib/rbs/unit_test/type_assertions.rb, line 246 def allows_error(*errors) yield rescue *errors => exn notify "Error allowed: #{exn.inspect}" end
assert_const_type(type, constant_name)
click to toggle source
# File rbs-3.6.1/lib/rbs/unit_test/type_assertions.rb, line 252 def assert_const_type(type, constant_name) constant = Object.const_get(constant_name) typecheck = RBS::Test::TypeCheck.new( self_class: constant.class, instance_class: instance_class, class_class: class_class, builder: builder, sample_size: 100, unchecked_classes: [] ) value_type = case type when String RBS::Parser.parse_type(type, variables: []) || raise else type end assert typecheck.value(constant, value_type), "`#{constant_name}` (#{constant.inspect}) must be compatible with given type `#{value_type}`" type_name = TypeName(constant_name).absolute! definition = env.constant_entry(type_name) assert definition, "Cannot find RBS type definition of `#{constant_name}`" case definition when RBS::Environment::ClassEntry, RBS::Environment::ModuleEntry definition_type = RBS::Types::ClassSingleton.new(name: type_name, location: nil) when RBS::Environment::ClassAliasEntry, RBS::Environment::ModuleAliasEntry type_name = env.normalize_type_name!(type_name) definition_type = RBS::Types::ClassSingleton.new(name: type_name, location: nil) when RBS::Environment::ConstantEntry definition_type = definition.decl.type end assert definition_type, "Cannot find RBS entry for `#{constant_name}`" definition_type or raise assert typecheck.value(constant, definition_type), "`#{constant_name}` (#{constant.inspect}) must be compatible with RBS type definition `#{definition_type}`" end
assert_send_type(method_type, receiver, method, *args, &block)
click to toggle source
# File rbs-3.6.1/lib/rbs/unit_test/type_assertions.rb, line 171 def assert_send_type(method_type, receiver, method, *args, &block) send_setup(method_type, receiver, method, args, block) do |method_type, trace, result, exception| typecheck = RBS::Test::TypeCheck.new( self_class: receiver.class, builder: builder, sample_size: 100, unchecked_classes: [], instance_class: instance_class, class_class: class_class ) errors = typecheck.method_call(method, method_type, trace, errors: []) assert_empty errors.map {|x| RBS::Test::Errors.to_string(x) }, "Call trace does not match with given method type: #{trace.inspect}" method_types = method_types(method) all_errors = method_types.map {|t| typecheck.method_call(method, t, trace, errors: []) } assert all_errors.any? {|es| es.empty? }, "Call trace does not match one of method definitions:\n #{trace.inspect}\n #{method_types.join(" | ")}" raise exception if exception result end end
assert_type(type, value)
click to toggle source
# File rbs-3.6.1/lib/rbs/unit_test/type_assertions.rb, line 293 def assert_type(type, value) typecheck = RBS::Test::TypeCheck.new( self_class: value.class, instance_class: _ = "No `instance` class allowed", class_class: _ = "No `class` class allowed", builder: builder, sample_size: 100, unchecked_classes: [] ) type = case type when String RBS::Parser.parse_type(type, variables: []) or raise else type end assert typecheck.value(value, type), "`#{value.inspect}` must be compatible with given type `#{type}`" end
break_from_block(value = nil)
click to toggle source
# File rbs-3.6.1/lib/rbs/unit_test/type_assertions.rb, line 331 def break_from_block(value = nil) raise "Cannot break without `@break_tag`" unless @break_tag throw @break_tag, value end
builder()
click to toggle source
# File rbs-3.6.1/lib/rbs/unit_test/type_assertions.rb, line 65 def builder (_ = self.class).builder end
class_class()
click to toggle source
# File rbs-3.6.1/lib/rbs/unit_test/type_assertions.rb, line 121 def class_class type, _ = target case type when RBS::Types::ClassSingleton, RBS::Types::ClassInstance Object.const_get(type.name.to_s).singleton_class end end
env()
click to toggle source
# File rbs-3.6.1/lib/rbs/unit_test/type_assertions.rb, line 61 def env (_ = self.class).env end
instance_class()
click to toggle source
# File rbs-3.6.1/lib/rbs/unit_test/type_assertions.rb, line 112 def instance_class type, _ = target case type when RBS::Types::ClassSingleton, RBS::Types::ClassInstance Object.const_get(type.name.to_s) end end
method_types(method)
click to toggle source
# File rbs-3.6.1/lib/rbs/unit_test/type_assertions.rb, line 230 def method_types(method) type, definition = target case type when Types::ClassInstance subst = RBS::Substitution.build(definition.type_params, type.args) definition.methods[method].method_types.map do |method_type| method_type.sub(subst) end when Types::ClassSingleton definition.methods[method].method_types else raise end end
pass(message = nil)
click to toggle source
# File rbs-3.6.1/lib/rbs/unit_test/type_assertions.rb, line 336 def pass(message = nil) assert true, message end
refute_send_type(method_type, receiver, method, *args, &block)
click to toggle source
# File rbs-3.6.1/lib/rbs/unit_test/type_assertions.rb, line 195 def refute_send_type(method_type, receiver, method, *args, &block) send_setup(method_type, receiver, method, args, block) do |method_type, trace, result, exception| method_type = method_type.update( block: if method_type.block RBS::Types::Block.new( type: method_type.block.type.with_return_type(RBS::Types::Bases::Any.new(location: nil)), required: method_type.block.required, self_type: nil ) end, type: method_type.type.with_return_type(RBS::Types::Bases::Any.new(location: nil)) ) typecheck = RBS::Test::TypeCheck.new( self_class: receiver.class, instance_class: instance_class, class_class: class_class, builder: builder, sample_size: 100, unchecked_classes: [] ) errors = typecheck.method_call(method, method_type, trace, errors: []) assert_operator exception, :is_a?, ::Exception assert_empty errors.map {|x| RBS::Test::Errors.to_string(x) } method_types = method_types(method) all_errors = method_types.map {|t| typecheck.method_call(method, t, trace, errors: []) } assert all_errors.all? {|es| es.size > 0 }, "Call trace unexpectedly matches one of method definitions:\n #{trace.inspect}\n #{method_types.join(" | ")}" result end end
send_setup(method_type, receiver, method, args, proc) { |mt, last_trace, result, exception| ... }
click to toggle source
# File rbs-3.6.1/lib/rbs/unit_test/type_assertions.rb, line 130 def send_setup(method_type, receiver, method, args, proc) mt = case method_type when String RBS::Parser.parse_method_type(method_type, variables: []) || raise when RBS::MethodType method_type end validate_simple_method_type(mt) trace = [] #: Array[Test::CallTrace] spy = Spy.wrap(receiver, method) spy.callback = -> (result) { trace << result } result = nil #: untyped exception = nil #: Exception? non_jump_exit = true begin result = catch do |tag| @break_tag = tag spy.wrapped_object.__send__(method, *args, &proc) ensure @break_tag = nil end non_jump_exit = false rescue Exception => exn exception = exn ensure if non_jump_exit && !exception raise "`break` nor `return` from blocks given to `assert_send_type` are prohibited. Use `#break_from_block` instead." end end last_trace = trace.last or raise yield(mt, last_trace, result, exception) end
target()
click to toggle source
# File rbs-3.6.1/lib/rbs/unit_test/type_assertions.rb, line 73 def target targets.last || (_ = self.class).target end
targets()
click to toggle source
# File rbs-3.6.1/lib/rbs/unit_test/type_assertions.rb, line 69 def targets @targets ||= [] end
testing(type_or_string) { || ... }
click to toggle source
# File rbs-3.6.1/lib/rbs/unit_test/type_assertions.rb, line 77 def testing(type_or_string) type = case type_or_string when String RBS::Parser.parse_type(type_or_string, variables: []) else type_or_string end definition = case type when RBS::Types::ClassInstance builder.build_instance(type.name) when RBS::Types::ClassSingleton builder.build_singleton(type.name) else raise "Test target should be class instance or class singleton: #{type}" end targets.push( [ type, #: target_type definition ] ) if block_given? begin yield ensure targets.pop end else [type, definition] end end
validate_simple_method_type(type)
click to toggle source
# File rbs-3.6.1/lib/rbs/unit_test/type_assertions.rb, line 323 def validate_simple_method_type(type) return if @allows_non_simple_method_type refute_predicate type, :has_self_type?, "`self` types is prohibited in method type: `#{type}`" refute_predicate type, :has_classish_type?, "`instance` and `class` types is prohibited in method type: `#{type}`" refute_predicate type, :with_nonreturn_void?, "`void` is only allowed at return type or generics parameters: `#{type}`" end