Runtime assertions for Ruby literal.fun
ruby
5
fork

Configure Feed

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

Improve unions

+104 -17
+25 -5
lib/literal.rb
··· 63 63 end 64 64 65 65 def self.subtype?(type, of:) 66 - type = type.block.call if Types::DeferredType === type 66 + supertype = of 67 + subtype = type 67 68 68 - (of == type) || case of 69 + subtype = subtype.block.call if Types::DeferredType === subtype 70 + 71 + return true if supertype == subtype 72 + 73 + case supertype 69 74 when Literal::Type 70 - of >= type 75 + supertype >= subtype 71 76 when Module 72 - (Module === type) ? of >= type : false 77 + case subtype 78 + when Module 79 + supertype >= subtype 80 + when Numeric 81 + Numeric >= supertype 82 + when String 83 + String >= supertype 84 + when Symbol 85 + Symbol >= supertype 86 + when ::Array 87 + ::Array >= supertype 88 + when ::Hash 89 + ::Hash >= supertype 90 + else 91 + false 92 + end 73 93 when Range 74 - of.cover?(type) 94 + supertype.cover?(subtype) 75 95 else 76 96 false 77 97 end
+21 -12
lib/literal/types/union_type.rb
··· 48 48 end 49 49 50 50 def each(&) 51 + @primitives.each(&) 51 52 @types.each(&) 52 53 end 53 54 54 55 def deconstruct 55 - @types.to_a 56 + to_a 56 57 end 57 58 58 59 def [](key) 59 - if @types.include?(key) 60 + if @primitives.include?(key) || @types.include?(key) 60 61 key 61 - else 62 - raise ArgumentError.new("#{key} not in #{inspect}") 63 62 end 64 63 end 65 64 65 + def fetch(key) 66 + self[key] or raise KeyError.new("Key not found: #{key.inspect}") 67 + end 68 + 66 69 def record_literal_type_errors(ctx) 67 - @types.each do |type| 70 + each do |type| 68 71 ctx.add_child(label: type.inspect, expected: type, actual: ctx.actual) 69 72 end 73 + 70 74 ctx.children.clear if ctx.children.none? { |c| c.children.any? } 71 75 end 72 76 73 77 def >=(other) 78 + types = @types 79 + primitives = @primitives 80 + 74 81 case other 75 82 when Literal::Types::UnionType 76 - other.types.all? do |other_type| 77 - @types.any? do |type| 78 - Literal.subtype?(type, of: other_type) 79 - end 83 + 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) } 80 85 end 81 - else 82 - @types.any? do |type| 83 - Literal.subtype?(other, of: type) 86 + 87 + 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) } 84 89 end 90 + 91 + types_have_at_least_one_subtype && primitives_have_at_least_one_subtype 92 + else 93 + types.any? { |t| Literal.subtype?(other, of: t) } || primitives.any? { |p| Literal.subtype?(other, of: p) } 85 94 end 86 95 end 87 96
+58
test/union.test.rb
··· 1 + # frozen_string_literal: true 2 + 3 + include Literal::Types 4 + 5 + test "#enumerability" do 6 + union = _Union(:a, :b, :c, 1, 2, 3, String, Integer) 7 + 8 + assert_equal union.to_a, [:a, :b, :c, 1, 2, 3, String, Integer] 9 + end 10 + 11 + test "#deconstruct" do 12 + union = _Union(:a, :b, :c, 1, 2, 3, String, Integer) 13 + 14 + assert_equal union.deconstruct, [:a, :b, :c, 1, 2, 3, String, Integer] 15 + end 16 + 17 + test "#[]" do 18 + union = _Union(:a, :b, :c, 1, 2, 3, String, Integer) 19 + 20 + assert_equal union[:a], :a 21 + assert_equal union[:b], :b 22 + assert_equal union[:c], :c 23 + assert_equal union[1], 1 24 + assert_equal union[2], 2 25 + assert_equal union[3], 3 26 + assert_equal union[String], String 27 + assert_equal union[Integer], Integer 28 + 29 + assert_equal union[:d], nil 30 + end 31 + 32 + test "#fetch" do 33 + union = _Union(:a, :b, :c, 1, 2, 3, String, Integer) 34 + 35 + assert_equal union.fetch(:a), :a 36 + assert_equal union.fetch(:b), :b 37 + assert_equal union.fetch(:c), :c 38 + assert_equal union.fetch(1), 1 39 + assert_equal union.fetch(2), 2 40 + assert_equal union.fetch(3), 3 41 + assert_equal union.fetch(String), String 42 + assert_equal union.fetch(Integer), Integer 43 + 44 + assert_raises(KeyError) { union.fetch(:d) } 45 + end 46 + 47 + test ">=" do 48 + assert _Union(:a, :b, :c) >= _Union(:a, :b, :c) 49 + assert _Union(:a, :b, :c) >= _Union(:a, :b) 50 + refute _Union(:a, :b, :c) >= _Union(:a, :b, :c, :d) 51 + 52 + assert _Union(:a, :b, :c) >= :a 53 + 54 + assert _Union(Integer, String) >= 1 55 + assert _Union(Integer, String) >= "1" 56 + assert _Union(Array, Hash) >= {} 57 + assert _Union(Array, Hash) >= [] 58 + end