Runtime assertions for Ruby literal.fun
ruby
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

Extract type tests into their own files

+781 -641
+1 -1
lib/literal/types/interface_type.rb
··· 5 5 # TODO: We can generate this and make it much more extensive. 6 6 METHOD_TYPE_MAPPINGS = { 7 7 :call => Set[Proc, Method], 8 - :to_proc => Set[Proc, Method], 8 + :to_proc => Set[Proc, Method, Symbol], 9 9 :to_s => Set[String], 10 10 }.freeze 11 11
+4 -11
lib/literal/types/union_type.rb
··· 2 2 3 3 class Literal::Types::UnionType 4 4 include Enumerable 5 + include Literal::Type 5 6 6 7 def initialize(*queue) 7 8 raise Literal::ArgumentError.new("_Union type must have at least one type.") if queue.size < 1 ··· 32 33 attr_reader :types, :primitives 33 34 34 35 def inspect 35 - "_Union(#{@types.inspect})" 36 + "_Union(#{to_a.map(&:inspect).join(', ')})" 36 37 end 37 38 38 39 def ===(value) ··· 66 67 self[key] or raise KeyError.new("Key not found: #{key.inspect}") 67 68 end 68 69 69 - def record_literal_type_errors(ctx) 70 - each do |type| 71 - ctx.add_child(label: type.inspect, expected: type, actual: ctx.actual) 72 - end 73 - 74 - ctx.children.clear if ctx.children.none? { |c| c.children.any? } 75 - end 76 - 77 70 def >=(other) 78 71 types = @types 79 72 primitives = @primitives ··· 81 74 case other 82 75 when Literal::Types::UnionType 83 76 types_have_at_least_one_subtype = other.types.all? do |other_type| 84 - primitives.any? { |p| Literal.subtype?(p, of: other_type) } || types.any? { |t| Literal.subtype?(t, of: other_type) } 77 + primitives.any? { |p| Literal.subtype?(other_type, of: p) } || types.any? { |t| Literal.subtype?(other_type, of: t) } 85 78 end 86 79 87 80 primitives_have_at_least_one_subtype = other.primitives.all? do |other_primitive| 88 - primitives.any? { |p| Literal.subtype?(p, of: other_primitive) } || types.any? { |t| Literal.subtype?(t, of: other_primitive) } 81 + primitives.any? { |p| Literal.subtype?(other_primitive, of: p) } || types.any? { |t| Literal.subtype?(other_primitive, of: t) } 89 82 end 90 83 91 84 types_have_at_least_one_subtype && primitives_have_at_least_one_subtype
-587
test/types.test.rb
··· 1 - # frozen_string_literal: true 2 - 3 - include Literal::Types 4 - 5 - def expect_type_error(expected:, actual:, message:) 6 - error = assert_raises(Literal::TypeError) do 7 - Literal.check(expected:, actual:) 8 - end 9 - 10 - assert_equal error.message, message 11 - end 12 - 13 - test "_Deferred" do 14 - recursive = _Hash( 15 - String, 16 - _Deferred { recursive } 17 - ) 18 - 19 - assert recursive === { 20 - "a" => { 21 - "b" => { 22 - "c" => { 23 - "d" => { 24 - "e" => { 25 - "f" => { 26 - "g" => {}, 27 - }, 28 - }, 29 - }, 30 - }, 31 - }, 32 - }, 33 - } 34 - 35 - refute recursive === { 36 - "a" => { 37 - "b" => { 1 => {} }, 38 - }, 39 - } 40 - 41 - assert _Deferred { Numeric } >= Integer 42 - assert _Deferred { Numeric } >= _Deferred { Integer } 43 - end 44 - 45 - test "_Array" do 46 - assert _Array(String) === [] 47 - assert _Array(String) === ["a", "b", "c"] 48 - 49 - refute _Array(String) === ["a", "b", 42] 50 - end 51 - 52 - test "_Boolean" do 53 - assert _Boolean === true 54 - assert _Boolean === false 55 - 56 - refute _Boolean === nil 57 - 58 - assert _Boolean >= true 59 - assert _Boolean >= false 60 - refute _Boolean >= nil 61 - assert _Boolean >= _Boolean 62 - end 63 - 64 - test "_Constraint with object constraints" do 65 - age_constraint = _Constraint(Integer, 18..) 66 - 67 - assert age_constraint === 18 68 - 69 - refute age_constraint === 17 70 - refute age_constraint === 17.5 71 - 72 - expect_type_error(expected: age_constraint, actual: 17, message: <<~MSG) 73 - Type mismatch 74 - 75 - _Constraint(Integer, 18..) 76 - Expected: 18.. 77 - Actual (Integer): 17 78 - MSG 79 - expect_type_error(expected: age_constraint, actual: 18.5, message: <<~MSG) 80 - Type mismatch 81 - 82 - _Constraint(Integer, 18..) 83 - Expected: Integer 84 - Actual (Float): 18.5 85 - MSG 86 - end 87 - 88 - test "_Constraint with property constraints" do 89 - age_constraint = _Constraint(Array, size: 2..3) 90 - 91 - assert age_constraint === [1, 2] 92 - assert age_constraint === [1, 2, 3] 93 - 94 - refute age_constraint === [1] 95 - refute age_constraint === [1, 2, 3, 4] 96 - refute age_constraint === Set[1, 2] 97 - 98 - expect_type_error(expected: age_constraint, actual: [], message: <<~MSG) 99 - Type mismatch 100 - 101 - .size 102 - Expected: 2..3 103 - Actual (Integer): 0 104 - MSG 105 - expect_type_error(expected: age_constraint, actual: nil, message: <<~MSG) 106 - Type mismatch 107 - 108 - _Constraint(Array, size: 2..3) 109 - Expected: Array 110 - Actual (NilClass): nil 111 - MSG 112 - expect_type_error(expected: _Constraint(String, foo: 1, size: Integer), actual: "string", message: <<~MSG) 113 - Type mismatch 114 - 115 - Expected: _Constraint(String, foo: 1, size: Integer) 116 - Actual (String): "string" 117 - MSG 118 - 119 - assert _Constraint(String) >= _Constraint(String) 120 - assert _Constraint(_Array(Enumerable)) >= _Constraint(_Array(Array)) 121 - assert _Constraint(Array, size: 1..5) >= _Constraint(Array, size: 1..5) 122 - assert _Constraint(Array, size: 1..3) >= _Constraint(Array, size: 1..2) 123 - assert _Constraint(Enumerable, Array) >= _Intersection(Array) 124 - assert _Constraint(_Array(Enumerable), name: _String(size: 1..5)) >= _Constraint(_Array(Enumerable), name: _String(size: 1..5)) 125 - 126 - refute _Constraint(Array, size: 1..2) >= _Constraint(Array, size: 1..3) 127 - refute _Constraint(String, size: 4) >= _Constraint(String, size: 1) 128 - end 129 - 130 - test "_Descendant" do 131 - assert _Descendant(Enumerable) === Array 132 - assert _Descendant(Enumerable) === Set 133 - 134 - refute _Descendant(Enumerable) === [] 135 - refute _Descendant(Enumerable) === String 136 - 137 - assert _Descendant(Enumerable) >= _Descendant(Array) 138 - assert _Descendant(Enumerable) >= _Descendant(Set) 139 - refute _Descendant(Enumerable) >= _Descendant(String) 140 - end 141 - 142 - test "_Falsy" do 143 - falsy_objects = Set[false, nil] 144 - truthy_objects = Fixtures::Objects - falsy_objects 145 - 146 - falsy_objects.each do |object| 147 - assert _Falsy === object 148 - end 149 - 150 - truthy_objects.each do |object| 151 - refute _Falsy === object 152 - end 153 - 154 - assert _Falsy >= _Falsy 155 - assert _Falsy >= false 156 - assert _Falsy >= nil 157 - 158 - refute _Falsy >= true 159 - refute _Falsy >= 0 160 - refute _Falsy >= "string" 161 - end 162 - 163 - test "_Float" do 164 - assert _Float(18.0..) === 18.0 165 - assert _Float(18.0..) === 19.5 166 - 167 - refute _Float(18.0..) === 17.99 168 - refute _Float(18.0..) === 42 169 - refute _Float(18.0..) === "string" 170 - refute _Float(18.0..) === nil 171 - end 172 - 173 - test "_Hash" do 174 - assert _Hash(String, Integer) === { "a" => 1, "b" => 2 } 175 - assert _Hash(Symbol, String) === { foo: "bar", baz: "qux" } 176 - 177 - refute _Hash(String, Integer) === { "a" => "1", "b" => 2 } 178 - refute _Hash(String, Integer) === { 1 => 2, 3 => 4 } 179 - refute _Hash(Symbol, String) === { "foo" => "bar", :baz => "qux" } 180 - 181 - assert _Hash(String, Numeric) >= _Hash(String, Integer) 182 - assert _Hash(Numeric, String) >= _Hash(Integer, String) 183 - assert _Hash(Symbol, Integer) >= _Hash(Symbol, Integer) 184 - refute _Hash(Symbol, Integer) >= _Hash(Symbol, Numeric) 185 - 186 - expect_type_error(expected: _Hash(Symbol, Integer), actual: { 1 => 2, :a => :b, :d => 2 }, message: <<~MSG) 187 - Type mismatch 188 - 189 - [] 190 - Expected: Symbol 191 - Actual (Integer): 1 192 - [:a] 193 - Expected: Integer 194 - Actual (Symbol): :b 195 - MSG 196 - expect_type_error(expected: _Hash(Symbol, Integer), actual: nil, message: <<~MSG) 197 - Type mismatch 198 - 199 - Expected: _Hash(Symbol, Integer) 200 - Actual (NilClass): nil 201 - MSG 202 - end 203 - 204 - test "_Integer" do 205 - assert _Integer(18..) === 18 206 - assert _Integer(18..) === 19 207 - 208 - refute _Integer(18..) === 17 209 - refute _Integer(18..) === 18.5 210 - refute _Integer(18..) === "string" 211 - refute _Integer(18..) === nil 212 - end 213 - 214 - test "_Interface" do 215 - enumerable_interface = _Interface(:each, :map, :select) 216 - 217 - assert enumerable_interface === [] 218 - assert enumerable_interface === Set.new 219 - 220 - refute enumerable_interface === 42 221 - refute enumerable_interface === "string" 222 - refute enumerable_interface === nil 223 - 224 - expect_type_error(expected: enumerable_interface, actual: nil, message: <<~MSG) 225 - Type mismatch 226 - 227 - Expected: _Interface(:each, :map, :select) 228 - Actual (NilClass): nil 229 - MSG 230 - 231 - assert _Interface(:a) >= _Interface(:a) 232 - assert _Interface(:a) >= _Interface(:a, :b) 233 - assert _Interface(:a, :b) >= _Interface(:a, :b) 234 - refute _Interface(:a, :b) >= _Interface(:a) 235 - refute _Interface(:a) >= _Interface(:b) 236 - assert _Interface(:call) >= _Callable 237 - assert _Interface(:to_proc) >= _Procable 238 - refute _Interface(:to_proc, :random_method) >= Proc 239 - end 240 - 241 - test "_Intersection" do 242 - type = _Intersection( 243 - _Interface(:size), 244 - _Interface(:each), 245 - ) 246 - 247 - assert type === [] 248 - assert type === Set.new 249 - 250 - refute type === "string" 251 - 252 - expect_type_error(actual: "string", expected: type, message: <<~MSG) 253 - Type mismatch 254 - 255 - _Intersection(_Interface(:size), _Interface(:each)) 256 - Expected: _Interface(:each) 257 - Actual (String): "string" 258 - MSG 259 - 260 - assert _Intersection(String) >= _Intersection(String) 261 - assert _Intersection(String) >= _Constraint(String, size: 1..5) 262 - 263 - refute _Intersection(String) >= _Constraint(Integer, size: 1..2) 264 - end 265 - 266 - test "_JSONData" do 267 - assert _JSONData === "string" 268 - assert _JSONData === 42 269 - assert _JSONData === 3.14 270 - assert _JSONData === true 271 - assert _JSONData === false 272 - assert _JSONData === nil 273 - assert _JSONData === { "key" => "value", "number" => 42 } 274 - assert _JSONData === [1, "two", 3.0, true, false, nil] 275 - 276 - assert _JSONData === { "nested_array" => [1, "two", { "key" => "value" }] } 277 - assert _JSONData === { "nested_hash" => { "key1" => "value1", "key2" => [1, 2, 3] } } 278 - assert _JSONData === [{ "key" => "value" }, [1, 2, 3], "string"] 279 - 280 - refute _JSONData === Object.new 281 - refute _JSONData === Set.new 282 - refute _JSONData === { key: "value" } 283 - refute _JSONData === [1, :symbol, "three"] 284 - refute _JSONData === { "nested_array" => [1, :symbol, { "key" => "value" }] } 285 - refute _JSONData === { "nested_hash" => { "key1" => "value1", "key2" => [1, :symbol, 3] } } 286 - refute _JSONData === [{ "key" => :value }, [1, 2, 3], "string"] 287 - 288 - assert _JSONData >= _JSONData 289 - assert _JSONData >= _Array(_JSONData) 290 - assert _JSONData >= _Hash(_JSONData, _JSONData) 291 - assert _JSONData >= String 292 - assert _JSONData >= _String(length: 10) 293 - assert _JSONData >= Float 294 - assert _JSONData >= _Float(5..10) 295 - assert _JSONData >= Integer 296 - assert _JSONData >= _Integer(5..10) 297 - assert _JSONData >= true 298 - assert _JSONData >= false 299 - assert _JSONData >= nil 300 - 301 - refute _JSONData >= Array # not compatible since we don’t know what’s inside the array 302 - refute _JSONData >= Hash # same as above 303 - 304 - expect_type_error(actual: { :key => "value", "string" => "string", "symbol" => :symbol, "array" => [1, 2, 3, :symbol], "hash" => { "key" => "value", "symbol" => :symbol } }, expected: _JSONData, message: <<~MSG) 305 - Type mismatch 306 - 307 - [] 308 - Expected: String 309 - Actual (Symbol): :key 310 - ["symbol"] 311 - Expected: _JSONData 312 - Actual (Symbol): :symbol 313 - ["array"] 314 - [3] 315 - Expected: _JSONData 316 - Actual (Symbol): :symbol 317 - ["hash"] 318 - ["symbol"] 319 - Expected: _JSONData 320 - Actual (Symbol): :symbol 321 - MSG 322 - end 323 - 324 - test "_Lambda" do 325 - assert _Lambda === -> {} 326 - assert _Lambda === -> (arg) { arg } 327 - assert _Lambda === lambda {} 328 - 329 - refute _Lambda === proc {} 330 - end 331 - 332 - test "_Map" do 333 - map = _Map(name: String, age: Integer) 334 - 335 - assert map === { name: "Alice", age: 42 } 336 - assert map === { name: "Bob", age: 18 } 337 - 338 - refute map === { name: "Alice", age: "42" } 339 - refute map === { name: "Bob", age: nil } 340 - refute map === { name: "Charlie" } 341 - refute map === { age: 30 } 342 - 343 - assert _Map(a: Enumerable, b: Numeric) >= _Map(a: Array, b: Integer, foo: String) 344 - refute _Map(a: Enumerable, b: Numeric) >= _Map(a: Array) 345 - refute _Map(a: Enumerable, b: Numeric) >= _Map(a: String, b: Integer) 346 - refute _Map(a: String) >= nil 347 - 348 - expect_type_error(expected: map, actual: { name: "Alice", age: "42" }, message: <<~MSG) 349 - Type mismatch 350 - 351 - [:age] 352 - Expected: Integer 353 - Actual (String): "42" 354 - MSG 355 - 356 - object_keys_map = _Map(**{ 1 => Integer, "2" => String, :symbol => _Nilable(Symbol) }) 357 - 358 - assert_equal object_keys_map.inspect, "_Map(#{{ 1 => Integer, '2' => String, :symbol => _Nilable(Symbol) }.inspect})" 359 - assert object_keys_map === { 1 => 2, "2" => "string" } 360 - assert object_keys_map === { 1 => 2, "2" => "string", :symbol => :foo } 361 - 362 - refute object_keys_map === {} 363 - refute object_keys_map === { 1 => 2 } 364 - 365 - expect_type_error(expected: object_keys_map, actual: { 1 => "1" }, message: <<~MSG) 366 - Type mismatch 367 - 368 - [1] 369 - Expected: Integer 370 - Actual (String): "1" 371 - ["2"] 372 - Expected: String 373 - Actual (NilClass): nil 374 - MSG 375 - end 376 - 377 - test "_Never" do 378 - Fixtures::Objects.each do |object| 379 - refute _Never === object 380 - end 381 - 382 - refute _Never === nil 383 - end 384 - 385 - test "_Nilable" do 386 - type = _Nilable(String) 387 - 388 - assert type === "string" 389 - assert type === nil 390 - 391 - refute type === 42 392 - refute type === :symbol 393 - refute type === [] 394 - 395 - assert _Nilable(String) >= String 396 - assert _Nilable(String) >= _Nilable(String) 397 - assert _Nilable(String) >= nil 398 - assert _Nilable(Enumerable) >= _Nilable(Array) 399 - assert _Nilable(Enumerable) >= Array 400 - refute _Nilable(Enumerable) >= String 401 - 402 - expect_type_error(expected: _Nilable(_Hash(Symbol, Integer)), actual: { 1 => 2, :a => :b, :d => 2 }, message: <<~MSG) 403 - Type mismatch 404 - 405 - [] 406 - Expected: Symbol 407 - Actual (Integer): 1 408 - [:a] 409 - Expected: Integer 410 - Actual (Symbol): :b 411 - MSG 412 - end 413 - 414 - test "_Not" do 415 - assert _Not(Integer) === "string" 416 - assert _Not(_Array(Integer)) === [1, "2", 3] 417 - assert _Array(_Not(Integer)) === ["2"] 418 - 419 - refute _Not(Integer) === 18 420 - refute _Not(_Array(Integer)) === [] 421 - refute _Not(_Array(Integer)) === [2] 422 - refute _Array(_Not(Integer)) === [1, "2"] 423 - 424 - assert _Not(Integer) >= _Not(Integer) 425 - assert _Not(Numeric) >= _Not(Integer) 426 - assert _Not(Integer) >= _Constraint(_Not(Integer), String) 427 - assert _Not(Integer) >= _Intersection(_Not(Integer), String) 428 - 429 - refute _Not(Integer) >= _Constraint(Integer, String) 430 - refute _Not(Integer) >= _Intersection(Integer, String) 431 - 432 - expect_type_error(expected: _Not(Integer), actual: 18, message: <<~MSG) 433 - Type mismatch 434 - 435 - Expected: _Not(Integer) 436 - Actual (Integer): 18 437 - MSG 438 - # TODO: can we distribute out the _Not over container types? 439 - expect_type_error(expected: _Not(_Array(Integer)), actual: [18], message: <<~MSG) 440 - Type mismatch 441 - 442 - Expected: _Not(_Array(Integer)) 443 - Actual (Array): [18] 444 - MSG 445 - expect_type_error(expected: _Array(_Not(Integer)), actual: [18, "2"], message: <<~MSG) 446 - Type mismatch 447 - 448 - [0] 449 - Expected: _Not(Integer) 450 - Actual (Integer): 18 451 - MSG 452 - end 453 - 454 - test "_Procable" do 455 - assert _Procable === proc {} 456 - assert _Procable === -> {} 457 - assert _Procable === method(:puts) 458 - 459 - refute _Procable === "string" 460 - refute _Procable === 42 461 - refute _Procable === nil 462 - end 463 - 464 - test "_Range" do 465 - assert _Range(Integer) === (1..10) 466 - assert _Range(Float) === (1.0..10.0) 467 - assert _Range(String) === ("a".."z") 468 - 469 - refute _Range(Integer) === (1.0..10.0) 470 - 471 - assert _Range(Numeric) >= _Range(Integer) 472 - assert _Range(Integer) >= _Range(Integer) 473 - refute _Range(Integer) >= _Range(Float) 474 - assert _Range(String) >= _Range(String) 475 - refute _Range(String) >= nil 476 - 477 - expect_type_error(expected: _Range(Integer), actual: (1.0..10.0), message: <<~MSG) 478 - Type mismatch 479 - 480 - Expected: _Range(Integer) 481 - Actual (Range): 1.0..10.0 482 - MSG 483 - end 484 - 485 - test "_Set" do 486 - assert _Set(String) === Set["a", "b", "c"] 487 - assert _Set(Integer) === Set[1, 2, 3] 488 - 489 - refute _Set(String) === Set[1, "a", :symbol] 490 - refute _Set(Integer) === Set["a", "b", "c"] 491 - refute _Set(String) === ["a", "b", "c"] 492 - 493 - assert _Set(String) >= _Set(String) 494 - refute _Set(String) >= _Set(Integer) 495 - assert _Set(Numeric) >= _Set(Integer) 496 - refute _Set(Numeric) >= Numeric 497 - 498 - expect_type_error(expected: _Set(String), actual: Set["1", 2, "3", nil], message: <<~MSG) 499 - Type mismatch 500 - 501 - [] 502 - Expected: String 503 - Actual (Integer): 2 504 - [] 505 - Expected: String 506 - Actual (NilClass): nil 507 - MSG 508 - end 509 - 510 - test "_String" do 511 - assert _String(_Interface(:to_s)) === "string" 512 - assert _String(size: 6) === "string" 513 - 514 - refute _String(_Interface(:non_existing_method)) === "string" 515 - refute _String(size: 5) === "string" 516 - end 517 - 518 - test "_Truthy" do 519 - truthy_objects = Fixtures::Objects - Set[false, nil] 520 - falsy_objects = Set[false, nil] 521 - 522 - truthy_objects.each do |object| 523 - assert _Truthy === object 524 - end 525 - 526 - falsy_objects.each do |object| 527 - refute _Truthy === object 528 - end 529 - 530 - assert _Truthy >= true 531 - assert _Truthy >= _Truthy 532 - refute _Truthy >= false 533 - refute _Truthy >= _Not(true) 534 - refute _Truthy >= _Not(_Truthy) 535 - assert _Truthy >= _Not(_Not(true)) 536 - assert _Truthy >= _Not(_Not(_Truthy)) 537 - end 538 - 539 - test "_Tuple" do 540 - assert _Tuple(String, Integer) === ["a", 1] 541 - assert _Tuple(Symbol, Float) === [:symbol, 3.14] 542 - 543 - refute _Tuple(String, Integer) === [1, "a"] 544 - refute _Tuple(String, Integer) === ["a", 1, 2] 545 - refute _Tuple(String, Integer) === ["a"] 546 - refute _Tuple(String, Integer) === nil 547 - 548 - assert _Tuple(String, Integer) >= _Tuple(String, Integer) 549 - refute _Tuple(String, Integer) >= _Tuple(String, Float) 550 - refute _Tuple(String, Integer) >= [String, Float] 551 - 552 - expect_type_error(expected: _Tuple(String, Integer), actual: [1, "a"], message: <<~ERROR) 553 - Type mismatch 554 - 555 - [0] 556 - Expected: String 557 - Actual (Integer): 1 558 - [1] 559 - Expected: Integer 560 - Actual (String): "a" 561 - ERROR 562 - 563 - expect_type_error(expected: _Tuple(String, Integer), actual: ["a", 1, 2], message: <<~ERROR) 564 - Type mismatch 565 - 566 - [2] 567 - Expected: _Never 568 - Actual (Integer): 2 569 - ERROR 570 - 571 - expect_type_error(expected: _Tuple(String, Integer), actual: ["a"], message: <<~ERROR) 572 - Type mismatch 573 - 574 - [1] 575 - Expected: Integer 576 - Actual (NilClass): nil 577 - ERROR 578 - end 579 - 580 - test "_Void" do 581 - Fixtures::Objects.each do |object| 582 - assert _Void === object 583 - end 584 - 585 - assert _Void >= nil 586 - assert _Void >= Object 587 - end
+10
test/types/_array.test.rb
··· 1 + # frozen_string_literal: true 2 + 3 + include Literal::Types 4 + 5 + test "===" do 6 + assert _Array(String) === [] 7 + assert _Array(String) === ["a", "b", "c"] 8 + 9 + refute _Array(String) === ["a", "b", 42] 10 + end
+18
test/types/_boolean.test.rb
··· 1 + # frozen_string_literal: true 2 + 3 + include Literal::Types 4 + 5 + test "===" do 6 + assert _Boolean === true 7 + assert _Boolean === false 8 + 9 + refute _Boolean === nil 10 + end 11 + 12 + test "hierarchy" do 13 + assert_subtype true, _Boolean 14 + assert_subtype false, _Boolean 15 + assert_subtype _Boolean, _Boolean 16 + 17 + refute_subtype nil, _Boolean 18 + end
+52
test/types/_constraint.test.rb
··· 1 + # frozen_string_literal: true 2 + 3 + include Literal::Types 4 + 5 + test "=== with object constraints" do 6 + age_constraint = _Constraint(Integer, 18..) 7 + 8 + assert age_constraint === 18 9 + 10 + refute age_constraint === 17 11 + refute age_constraint === 17.5 12 + end 13 + 14 + test "hierarchy" do 15 + assert_subtype _Constraint(String), _Constraint(String) 16 + assert_subtype _Constraint(_Array(Array)), _Constraint(_Array(Enumerable)) 17 + assert_subtype _Constraint(Array, size: 1..5), _Constraint(Array, size: 1..5) 18 + assert_subtype _Constraint(Array, size: 1..2), _Constraint(Array, size: 1..3) 19 + assert_subtype _Intersection(Array), _Constraint(Enumerable, Array) 20 + assert_subtype _Constraint(_Array(Enumerable), name: _String(size: 1..5)), _Constraint(_Array(Enumerable), name: _String(size: 1..5)) 21 + 22 + refute_subtype _Constraint(Array, size: 1..3), _Constraint(Array, size: 1..2) 23 + refute_subtype _Constraint(String, size: 1), _Constraint(String, size: 4) 24 + end 25 + 26 + test "error message with object constraints" do 27 + error = assert_raises Literal::TypeError do 28 + Literal.check( 29 + expected: _Constraint(Integer, 18..), 30 + actual: 17 31 + ) 32 + end 33 + 34 + assert_equal error.message, <<~MSG 35 + Type mismatch 36 + 37 + _Constraint(Integer, 18..) 38 + Expected: 18.. 39 + Actual (Integer): 17 40 + MSG 41 + end 42 + 43 + test "=== with property constraints" do 44 + age_constraint = _Constraint(Array, size: 2..3) 45 + 46 + assert age_constraint === [1, 2] 47 + assert age_constraint === [1, 2, 3] 48 + 49 + refute age_constraint === [1] 50 + refute age_constraint === [1, 2, 3, 4] 51 + refute age_constraint === Set[1, 2] 52 + end
+37
test/types/_deferred.test.rb
··· 1 + # frozen_string_literal: true 2 + 3 + include Literal::Types 4 + 5 + test "===" do 6 + recursive = _Hash( 7 + String, 8 + _Deferred { recursive } 9 + ) 10 + 11 + assert recursive === { 12 + "a" => { 13 + "b" => { 14 + "c" => { 15 + "d" => { 16 + "e" => { 17 + "f" => { 18 + "g" => {}, 19 + }, 20 + }, 21 + }, 22 + }, 23 + }, 24 + }, 25 + } 26 + 27 + refute recursive === { 28 + "a" => { 29 + "b" => { 1 => {} }, 30 + }, 31 + } 32 + end 33 + 34 + test "hirearchy" do 35 + assert_subtype Integer, _Deferred { Numeric } 36 + assert_subtype _Deferred { Integer }, _Deferred { Numeric } 37 + end
+19
test/types/_descendant.test.rb
··· 1 + # frozen_string_literal: true 2 + 3 + include Literal::Types 4 + 5 + test "===" do 6 + assert _Descendant(Enumerable) === Array 7 + assert _Descendant(Enumerable) === Set 8 + 9 + refute _Descendant(Enumerable) === [] 10 + refute _Descendant(Enumerable) === String 11 + end 12 + 13 + test "hierarchy" do 14 + assert_subtype _Descendant(Array), _Descendant(Enumerable) 15 + assert_subtype _Descendant(Set), _Descendant(Enumerable) 16 + 17 + refute_subtype _Descendant(Enumerable), _Descendant(Array) 18 + refute_subtype _Descendant(String), _Descendant(Enumerable) 19 + end
+26
test/types/_falsy.test.rb
··· 1 + # frozen_string_literal: true 2 + 3 + include Literal::Types 4 + 5 + test "===" do 6 + falsy_objects = Set[false, nil] 7 + truthy_objects = Fixtures::Objects - falsy_objects 8 + 9 + falsy_objects.each do |object| 10 + assert _Falsy === object 11 + end 12 + 13 + truthy_objects.each do |object| 14 + refute _Falsy === object 15 + end 16 + end 17 + 18 + test "hierarchy" do 19 + assert_subtype _Falsy, _Falsy 20 + assert_subtype false, _Falsy 21 + assert_subtype nil, _Falsy 22 + 23 + refute_subtype true, _Falsy 24 + refute_subtype 0, _Falsy 25 + refute_subtype "string", _Falsy 26 + end
+13
test/types/_float.test.rb
··· 1 + # frozen_string_literal: true 2 + 3 + include Literal::Types 4 + 5 + test "===" do 6 + assert _Float(18.0..) === 18.0 7 + assert _Float(18.0..) === 19.5 8 + 9 + refute _Float(18.0..) === 17.99 10 + refute _Float(18.0..) === 42 11 + refute _Float(18.0..) === "string" 12 + refute _Float(18.0..) === nil 13 + end
+54
test/types/_hash.test.rb
··· 1 + # frozen_string_literal: true 2 + 3 + include Literal::Types 4 + 5 + test "===" do 6 + assert _Hash(String, Integer) === { "a" => 1, "b" => 2 } 7 + assert _Hash(Symbol, String) === { foo: "bar", baz: "qux" } 8 + 9 + refute _Hash(String, Integer) === { "a" => "1", "b" => 2 } 10 + refute _Hash(String, Integer) === { 1 => 2, 3 => 4 } 11 + refute _Hash(Symbol, String) === { "foo" => "bar", :baz => "qux" } 12 + end 13 + 14 + test "hierarchy" do 15 + assert_subtype _Hash(String, Integer), _Hash(String, Numeric) 16 + assert_subtype _Hash(Integer, String), _Hash(Numeric, String) 17 + assert_subtype _Hash(Symbol, Integer), _Hash(Symbol, Integer) 18 + 19 + refute_subtype _Hash(Symbol, Numeric), _Hash(Symbol, Integer) 20 + end 21 + 22 + test "key error" do 23 + error = assert_raises Literal::TypeError do 24 + Literal.check( 25 + expected: _Hash(Symbol, Integer), actual: { 1 => 2, :a => :b, :d => 2 } 26 + ) 27 + end 28 + 29 + assert_equal error.message, <<~MSG 30 + Type mismatch 31 + 32 + [] 33 + Expected: Symbol 34 + Actual (Integer): 1 35 + [:a] 36 + Expected: Integer 37 + Actual (Symbol): :b 38 + MSG 39 + end 40 + 41 + test "top level error" do 42 + error = assert_raises Literal::TypeError do 43 + Literal.check( 44 + expected: _Hash(Symbol, Integer), actual: nil 45 + ) 46 + end 47 + 48 + assert_equal error.message, <<~MSG 49 + Type mismatch 50 + 51 + Expected: _Hash(Symbol, Integer) 52 + Actual (NilClass): nil 53 + MSG 54 + end
+13
test/types/_integer.test.rb
··· 1 + # frozen_string_literal: true 2 + 3 + include Literal::Types 4 + 5 + test "===" do 6 + assert _Integer(18..) === 18 7 + assert _Integer(18..) === 19 8 + 9 + refute _Integer(18..) === 17 10 + refute _Integer(18..) === 18.5 11 + refute _Integer(18..) === "string" 12 + refute _Integer(18..) === nil 13 + end
+41
test/types/_interface.test.rb
··· 1 + # frozen_string_literal: true 2 + 3 + include Literal::Types 4 + 5 + test "===" do 6 + enumerable_interface = _Interface(:each, :map, :select) 7 + 8 + assert enumerable_interface === [] 9 + assert enumerable_interface === Set.new 10 + 11 + refute enumerable_interface === 42 12 + refute enumerable_interface === "string" 13 + refute enumerable_interface === nil 14 + end 15 + 16 + test "hierarchy" do 17 + assert_subtype _Interface(:a), _Interface(:a) 18 + assert_subtype _Interface(:a, :b), _Interface(:a) 19 + assert_subtype _Interface(:a, :b), _Interface(:a, :b) 20 + assert_subtype _Callable, _Interface(:call) 21 + assert_subtype _Procable, _Interface(:to_proc) 22 + 23 + refute_subtype _Interface(:b), _Interface(:a) 24 + refute_subtype _Interface(:a), _Interface(:a, :b) 25 + refute_subtype Proc, _Interface(:to_proc, :random_method) 26 + end 27 + 28 + test "error message" do 29 + error = assert_raises Literal::TypeError do 30 + Literal.check( 31 + expected: _Interface(:each, :map, :select), actual: nil 32 + ) 33 + end 34 + 35 + assert_equal error.message, <<~MSG 36 + Type mismatch 37 + 38 + Expected: _Interface(:each, :map, :select) 39 + Actual (NilClass): nil 40 + MSG 41 + end
+42
test/types/_intersection.test.rb
··· 1 + # frozen_string_literal: true 2 + 3 + include Literal::Types 4 + 5 + test "===" do 6 + type = _Intersection( 7 + _Interface(:size), 8 + _Interface(:each), 9 + ) 10 + 11 + assert type === [] 12 + assert type === Set.new 13 + 14 + refute type === "string" 15 + end 16 + 17 + test "hierarchy" do 18 + assert_subtype _Intersection(String), _Intersection(String) 19 + assert_subtype _Constraint(String, size: 1..5), _Intersection(String) 20 + 21 + refute_subtype _Constraint(Integer, size: 1..2), _Intersection(String) 22 + end 23 + 24 + test "error message" do 25 + error = assert_raises(Literal::TypeError) do 26 + Literal.check( 27 + actual: "string", 28 + expected: _Intersection( 29 + _Interface(:size), 30 + _Interface(:each), 31 + ) 32 + ) 33 + end 34 + 35 + assert_equal error.message, <<~MSG 36 + Type mismatch 37 + 38 + _Intersection(_Interface(:size), _Interface(:each)) 39 + Expected: _Interface(:each) 40 + Actual (String): "string" 41 + MSG 42 + end
+101
test/types/_json_data.test.rb
··· 1 + # frozen_string_literal: true 2 + 3 + include Literal::Types 4 + 5 + test "===" do 6 + assert _JSONData === "string" 7 + assert _JSONData === 42 8 + assert _JSONData === 3.14 9 + assert _JSONData === true 10 + assert _JSONData === false 11 + assert _JSONData === nil 12 + assert _JSONData === { "key" => "value", "number" => 42 } 13 + assert _JSONData === [1, "two", 3.0, true, false, nil] 14 + 15 + assert _JSONData === { "nested_array" => [1, "two", { "key" => "value" }] } 16 + assert _JSONData === { "nested_hash" => { "key1" => "value1", "key2" => [1, 2, 3] } } 17 + assert _JSONData === [{ "key" => "value" }, [1, 2, 3], "string"] 18 + 19 + refute _JSONData === Object.new 20 + refute _JSONData === Set.new 21 + refute _JSONData === { key: "value" } 22 + refute _JSONData === [1, :symbol, "three"] 23 + refute _JSONData === { "nested_array" => [1, :symbol, { "key" => "value" }] } 24 + refute _JSONData === { "nested_hash" => { "key1" => "value1", "key2" => [1, :symbol, 3] } } 25 + refute _JSONData === [{ "key" => :value }, [1, 2, 3], "string"] 26 + end 27 + 28 + test "hierarchy" do 29 + assert_subtype _JSONData, _JSONData 30 + 31 + assert_subtype nil, _JSONData 32 + assert_subtype false, _JSONData 33 + assert_subtype true, _JSONData 34 + assert_subtype Float, _JSONData 35 + assert_subtype String, _JSONData 36 + assert_subtype Integer, _JSONData 37 + 38 + assert_subtype _Array(_JSONData), _JSONData 39 + assert_subtype _Array(nil), _JSONData 40 + assert_subtype _Array(false), _JSONData 41 + assert_subtype _Array(true), _JSONData 42 + assert_subtype _Array(Float), _JSONData 43 + assert_subtype _Array(String), _JSONData 44 + assert_subtype _Array(Integer), _JSONData 45 + 46 + assert_subtype _Hash(_JSONData, _JSONData), _JSONData 47 + assert_subtype _Hash(nil, _JSONData), _JSONData 48 + assert_subtype _Hash(false, _JSONData), _JSONData 49 + assert_subtype _Hash(true, _JSONData), _JSONData 50 + assert_subtype _Hash(Float, _JSONData), _JSONData 51 + assert_subtype _Hash(String, _JSONData), _JSONData 52 + assert_subtype _Hash(Integer, _JSONData), _JSONData 53 + 54 + assert_subtype _Hash(_JSONData, nil), _JSONData 55 + assert_subtype _Hash(_JSONData, false), _JSONData 56 + assert_subtype _Hash(_JSONData, true), _JSONData 57 + assert_subtype _Hash(_JSONData, Float), _JSONData 58 + assert_subtype _Hash(_JSONData, String), _JSONData 59 + assert_subtype _Hash(_JSONData, Integer), _JSONData 60 + 61 + assert_subtype _Float(5..10), _JSONData 62 + assert_subtype _String(length: 10), _JSONData 63 + assert_subtype _Integer(5..10), _JSONData 64 + 65 + # not compatible since we don’t know what’s inside the array 66 + refute_subtype Array, _JSONData 67 + 68 + # not compatible since we don’t know what’s inside the hash 69 + refute_subtype Hash, _JSONData 70 + 71 + # not compatible since we know the array contains symbols 72 + refute_subtype _Array(Symbol), _JSONData 73 + end 74 + 75 + test "error message" do 76 + error = assert_raises(Literal::TypeError) do 77 + Literal.check( 78 + actual: { :key => "value", "string" => "string", "symbol" => :symbol, "array" => [1, 2, 3, :symbol], "hash" => { "key" => "value", "symbol" => :symbol } }, 79 + expected: _JSONData 80 + ) 81 + end 82 + 83 + assert_equal error.message, <<~MSG 84 + Type mismatch 85 + 86 + [] 87 + Expected: String 88 + Actual (Symbol): :key 89 + ["symbol"] 90 + Expected: _JSONData 91 + Actual (Symbol): :symbol 92 + ["array"] 93 + [3] 94 + Expected: _JSONData 95 + Actual (Symbol): :symbol 96 + ["hash"] 97 + ["symbol"] 98 + Expected: _JSONData 99 + Actual (Symbol): :symbol 100 + MSG 101 + end
+11
test/types/_lambda.test.rb
··· 1 + # frozen_string_literal: true 2 + 3 + include Literal::Types 4 + 5 + test "===" do 6 + assert _Lambda === -> {} 7 + assert _Lambda === -> (arg) { arg } 8 + assert _Lambda === lambda {} 9 + 10 + refute _Lambda === proc {} 11 + end
+39
test/types/_map.test.rb
··· 1 + # frozen_string_literal: true 2 + 3 + include Literal::Types 4 + 5 + test "===" do 6 + map = _Map(name: String, age: Integer) 7 + 8 + assert map === { name: "Alice", age: 42 } 9 + assert map === { name: "Bob", age: 18 } 10 + 11 + refute map === { name: "Alice", age: "42" } 12 + refute map === { name: "Bob", age: nil } 13 + refute map === { name: "Charlie" } 14 + refute map === { age: 30 } 15 + end 16 + 17 + test "hierarchy" do 18 + assert_subtype _Map(a: Array, b: Integer, foo: String), _Map(a: Enumerable, b: Numeric) 19 + refute_subtype _Map(a: Array), _Map(a: Enumerable, b: Numeric) 20 + refute_subtype _Map(a: String, b: Integer), _Map(a: Enumerable, b: Numeric) 21 + refute_subtype nil, _Map(a: String) 22 + end 23 + 24 + test "error message" do 25 + error = assert_raises Literal::TypeError do 26 + Literal.check( 27 + expected: _Map(name: String, age: Integer), 28 + actual: { name: "Alice", age: "42" } 29 + ) 30 + end 31 + 32 + assert_equal error.message, <<~MSG 33 + Type mismatch 34 + 35 + [:age] 36 + Expected: Integer 37 + Actual (String): "42" 38 + MSG 39 + end
+11
test/types/_never.test.rb
··· 1 + # frozen_string_literal: true 2 + 3 + include Literal::Types 4 + 5 + test "===" do 6 + Fixtures::Objects.each do |object| 7 + refute _Never === object 8 + end 9 + 10 + refute _Never === nil 11 + end
+44
test/types/_nilable.test.rb
··· 1 + # frozen_string_literal: true 2 + 3 + include Literal::Types 4 + 5 + test "===" do 6 + type = _Nilable(String) 7 + 8 + assert type === "string" 9 + assert type === nil 10 + 11 + refute type === 42 12 + refute type === :symbol 13 + refute type === [] 14 + end 15 + 16 + test "hierarchy" do 17 + assert_subtype String, _Nilable(String) 18 + assert_subtype _Nilable(String), _Nilable(String) 19 + assert_subtype nil, _Nilable(String) 20 + assert_subtype _Nilable(Array), _Nilable(Enumerable) 21 + assert_subtype Array, _Nilable(Enumerable) 22 + 23 + refute_subtype String, _Nilable(Enumerable) 24 + end 25 + 26 + test "error message" do 27 + error = assert_raises Literal::TypeError do 28 + Literal.check( 29 + expected: _Nilable(_Hash(Symbol, Integer)), 30 + actual: { 1 => 2, :a => :b, :d => 2 } 31 + ) 32 + end 33 + 34 + assert_equal error.message, <<~MSG 35 + Type mismatch 36 + 37 + [] 38 + Expected: Symbol 39 + Actual (Integer): 1 40 + [:a] 41 + Expected: Integer 42 + Actual (Symbol): :b 43 + MSG 44 + end
+40
test/types/_not.test.rb
··· 1 + # frozen_string_literal: true 2 + 3 + include Literal::Types 4 + 5 + test "===" do 6 + assert _Not(Integer) === "string" 7 + assert _Not(_Array(Integer)) === [1, "2", 3] 8 + assert _Array(_Not(Integer)) === ["2"] 9 + 10 + refute _Not(Integer) === 18 11 + refute _Not(_Array(Integer)) === [] 12 + refute _Not(_Array(Integer)) === [2] 13 + refute _Array(_Not(Integer)) === [1, "2"] 14 + end 15 + 16 + test "hierarchy" do 17 + assert_subtype _Not(Integer), _Not(Integer) 18 + assert_subtype _Not(Integer), _Not(Numeric) 19 + assert_subtype _Constraint(_Not(Integer), String), _Not(Integer) 20 + assert_subtype _Intersection(_Not(Integer), String), _Not(Integer) 21 + 22 + refute_subtype _Constraint(Integer, String), _Not(Integer) 23 + refute_subtype _Intersection(Integer, String), _Not(Integer) 24 + end 25 + 26 + test "error message" do 27 + error = assert_raises Literal::TypeError do 28 + Literal.check( 29 + expected: _Not(Integer), 30 + actual: 18 31 + ) 32 + end 33 + 34 + assert_equal error.message, <<~MSG 35 + Type mismatch 36 + 37 + Expected: _Not(Integer) 38 + Actual (Integer): 18 39 + MSG 40 + end
+24
test/types/_procable.test.rb
··· 1 + # frozen_string_literal: true 2 + 3 + include Literal::Types 4 + 5 + test "===" do 6 + assert _Procable === proc {} 7 + assert _Procable === -> {} 8 + assert _Procable === method(:puts) 9 + 10 + refute _Procable === "string" 11 + refute _Procable === 42 12 + refute _Procable === nil 13 + end 14 + 15 + test "hierarchy" do 16 + assert_subtype _Procable, _Procable 17 + assert_subtype _Lambda, _Procable 18 + 19 + assert_subtype Method, _Procable 20 + assert_subtype Proc, _Procable 21 + assert_subtype Symbol, _Procable 22 + 23 + refute_subtype String, _Procable 24 + end
+33
test/types/_range.test.rb
··· 1 + # frozen_string_literal: true 2 + 3 + include Literal::Types 4 + 5 + test "_Range" do 6 + assert _Range(Integer) === (1..10) 7 + assert _Range(Float) === (1.0..10.0) 8 + assert _Range(String) === ("a".."z") 9 + 10 + refute _Range(Integer) === (1.0..10.0) 11 + end 12 + 13 + test "hierarchy" do 14 + assert_subtype _Range(Integer), _Range(Numeric) 15 + assert_subtype _Range(Integer), _Range(Integer) 16 + assert_subtype _Range(String), _Range(String) 17 + 18 + refute_subtype _Range(Float), _Range(Integer) 19 + refute_subtype nil, _Range(String) 20 + end 21 + 22 + test "type error" do 23 + message = assert_raises(Literal::TypeError) do 24 + Literal.check(actual: (1.0..10.0), expected: _Range(Integer)) 25 + end 26 + 27 + assert_equal message.message, <<~MSG 28 + Type mismatch 29 + 30 + Expected: _Range(Integer) 31 + Actual (Range): 1.0..10.0 32 + MSG 33 + end
+37
test/types/_set.test.rb
··· 1 + # frozen_string_literal: true 2 + 3 + include Literal::Types 4 + 5 + test "_Set" do 6 + assert _Set(String) === Set["a", "b", "c"] 7 + assert _Set(Integer) === Set[1, 2, 3] 8 + 9 + refute _Set(String) === Set[1, "a", :symbol] 10 + refute _Set(Integer) === Set["a", "b", "c"] 11 + refute _Set(String) === ["a", "b", "c"] 12 + end 13 + 14 + test "hierarchy" do 15 + assert_subtype _Set(String), _Set(String) 16 + assert_subtype _Set(Integer), _Set(Numeric) 17 + 18 + refute_subtype _Set(Integer), _Set(String) 19 + refute_subtype Numeric, _Set(Numeric) 20 + end 21 + 22 + test "error message" do 23 + error = assert_raises(Literal::TypeError) do 24 + Literal.check(expected: _Set(String), actual: Set["1", 2, "3", nil]) 25 + end 26 + 27 + assert_equal error.message, <<~MSG 28 + Type mismatch 29 + 30 + [] 31 + Expected: String 32 + Actual (Integer): 2 33 + [] 34 + Expected: String 35 + Actual (NilClass): nil 36 + MSG 37 + end
+11
test/types/_string.test.rb
··· 1 + # frozen_string_literal: true 2 + 3 + include Literal::Types 4 + 5 + test "===" do 6 + assert _String(_Interface(:to_s)) === "string" 7 + assert _String(size: 6) === "string" 8 + 9 + refute _String(_Interface(:non_existing_method)) === "string" 10 + refute _String(size: 5) === "string" 11 + end
+27
test/types/_truthy.test.rb
··· 1 + # frozen_string_literal: true 2 + 3 + include Literal::Types 4 + 5 + test "===" do 6 + truthy_objects = Fixtures::Objects - Set[false, nil] 7 + falsy_objects = Set[false, nil] 8 + 9 + truthy_objects.each do |object| 10 + assert _Truthy === object 11 + end 12 + 13 + falsy_objects.each do |object| 14 + refute _Truthy === object 15 + end 16 + end 17 + 18 + test "hierarchy" do 19 + assert_subtype true, _Truthy 20 + assert_subtype _Truthy, _Truthy 21 + assert_subtype _Not(_Not(true)), _Truthy 22 + assert_subtype _Not(_Not(_Truthy)), _Truthy 23 + 24 + refute_subtype false, _Truthy 25 + refute_subtype _Not(true), _Truthy 26 + refute_subtype _Not(_Truthy), _Truthy 27 + end
+39
test/types/_tuple.test.rb
··· 1 + # frozen_string_literal: true 2 + 3 + include Literal::Types 4 + 5 + test "===" do 6 + assert _Tuple(String, Integer) === ["a", 1] 7 + assert _Tuple(Symbol, Float) === [:symbol, 3.14] 8 + 9 + refute _Tuple(String, Integer) === [1, "a"] 10 + refute _Tuple(String, Integer) === ["a", 1, 2] 11 + refute _Tuple(String, Integer) === ["a"] 12 + refute _Tuple(String, Integer) === nil 13 + end 14 + 15 + test "hierarchy" do 16 + assert_subtype _Tuple(String, Integer), _Tuple(String, Integer) 17 + 18 + refute_subtype _Tuple(String, Float), _Tuple(String, Integer) 19 + end 20 + 21 + test "error message" do 22 + error = assert_raises(Literal::TypeError) do 23 + Literal.check( 24 + expected: _Tuple(String, Integer), 25 + actual: [1, "a"] 26 + ) 27 + end 28 + 29 + assert_equal error.message, <<~ERROR 30 + Type mismatch 31 + 32 + [0] 33 + Expected: String 34 + Actual (Integer): 1 35 + [1] 36 + Expected: Integer 37 + Actual (String): "a" 38 + ERROR 39 + end
+19 -42
test/types/_union.test.rb
··· 52 52 assert_raises(KeyError) { union.fetch(:d) } 53 53 end 54 54 55 - test ">=" do 56 - assert _Union(:a, :b, :c) >= _Union(:a, :b, :c) 57 - assert _Union(:a, :b, :c) >= _Union(:a, :b) 58 - refute _Union(:a, :b, :c) >= _Union(:a, :b, :c, :d) 59 - 60 - assert _Union(:a, :b, :c) >= :a 55 + test "hierarchy" do 56 + assert_subtype _Union(:a), _Union(:a) 57 + assert_subtype _Union(:a, :b, :c), _Union(:a, :b, :c) 58 + assert_subtype _Union(:a, :b, :c), _Union(:a, :b, :c, :d) 61 59 62 - assert _Union(Integer, String) >= 1 63 - assert _Union(Integer, String) >= "1" 64 - assert _Union(Array, Hash) >= {} 65 - assert _Union(Array, Hash) >= [] 60 + assert_subtype _Union(Integer), _Union(Numeric) 61 + assert_subtype Integer, _Union(Numeric) 62 + assert_subtype 1, _Union(Integer) 63 + assert_subtype _Union(1, 2, 3), _Union(Integer) 66 64 end 67 65 68 - test "_Union with primitives" do 66 + test "===" do 69 67 position = _Union(:top, :right, :bottom, :left, Integer) 70 68 71 69 assert position === :top ··· 84 82 _Union(Symbol, Float), 85 83 ) 86 84 87 - assert_equal type.inspect, "_Union([String, Integer, Symbol, Float])" 85 + assert_equal type.inspect, "_Union(String, Integer, Symbol, Float)" 88 86 end 89 87 90 - test "_Union matching" do 91 - type = _Union(String, Integer) 88 + test "error message" do 89 + error = assert_raises Literal::TypeError do 90 + Literal.check( 91 + expected: _Union(String, Integer), 92 + actual: :symbol 93 + ) 94 + end 92 95 93 - assert type === "string" 94 - assert type === 42 95 - 96 - refute type === :symbol 97 - refute type === [] 98 - refute type === nil 99 - 100 - assert _Union(String, Integer) >= _Union(String, Integer) 101 - refute _Union(String, Integer) >= _Union(String, Float) 102 - assert _Union(String, Integer) >= String 103 - refute _Union(String, Integer) >= Numeric 104 - assert _Union(String, Numeric) >= Float 105 - 106 - expect_type_error(expected: type, actual: :symbol, message: <<~ERROR) 96 + assert_equal error.message, <<~ERROR 107 97 Type mismatch 108 98 109 - Expected: _Union([String, Integer]) 99 + Expected: _Union(String, Integer) 110 100 Actual (Symbol): :symbol 111 - ERROR 112 - 113 - expect_type_error(expected: _Union(_Array(String), _Array(Integer)), actual: [nil], message: <<~ERROR) 114 - Type mismatch 115 - 116 - _Array(String) 117 - [0] 118 - Expected: String 119 - Actual (NilClass): nil 120 - _Array(Integer) 121 - [0] 122 - Expected: Integer 123 - Actual (NilClass): nil 124 101 ERROR 125 102 end
+15
test/types/_void.test.rb
··· 1 + # frozen_string_literal: true 2 + 3 + include Literal::Types 4 + 5 + test "===" do 6 + Fixtures::Objects.each do |object| 7 + assert _Void === object 8 + end 9 + end 10 + 11 + test "hierarchy" do 12 + assert_subtype _Void, _Void 13 + assert_subtype nil, _Void 14 + assert_subtype Object, _Void 15 + end