Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions lib/literal/enum.rb
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,7 @@ def __after_defined__
index = @members.group_by(&block).freeze

index.each do |key, values|
unless type === key
raise Literal::TypeError.expected(key, to_be_a: type)
end
Literal.check(key, type)

if unique && values.size > 1
raise ArgumentError.new("The index #{name} is not unique.")
Expand Down
5 changes: 2 additions & 3 deletions lib/literal/errors/type_error.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ def to_h
children: @children.map(&:to_h),
}
end

alias to_hash to_h
end

def initialize(context:)
Expand Down Expand Up @@ -87,7 +85,8 @@ def message
end

def deconstruct_keys(keys)
to_h.slice(*keys)
h = to_h
keys ? h.slice(*keys) : h
end

def to_h
Expand Down
12 changes: 12 additions & 0 deletions test/enum.test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -227,3 +227,15 @@ class SymbolTypedEnum < Literal::Enum(Symbol)
match { Color::Red => Color[1] }
match { Color::Red => Color[hex: "#FF0000"] }
end

test "index with wrong type raises Literal::TypeError" do
assert_raises(Literal::TypeError) do
Class.new(Literal::Enum(Integer)) do
index :bad_index, String, &:value

const_set(:A, new(1))

__after_defined__
end
end
end
40 changes: 30 additions & 10 deletions test/type_error.test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,42 @@

Age = Literal::Value(Integer, 18..)

test do
test "has message" do
Age.new(17)
rescue => error
assert_equal error.class, Literal::TypeError
assert_equal error.message, "Type mismatch\n\n" \
" _Constraint(Integer, 18..)\n" \
" Expected: 18..\n" \
" Actual (Integer): 17\n"
end

test "deconstruct_keys extracts specific keys" do
Age.new(17)
rescue Literal::TypeError => error
result = error.deconstruct_keys([:actual, :expected])

assert_equal result[:actual], 17
assert_equal result[:expected].class, Literal::Types::ConstraintType
end

# deconstruct_keys
key_names = [:receiver, :method, :label, :actual]
exp_keys = {
receiver: nil,
method: nil,
label: nil,
actual: 17,
}
assert_equal error.deconstruct_keys(key_names), exp_keys
test "deconstruct_keys with nil returns all keys" do
Age.new(17)
rescue Literal::TypeError => error
result = error.deconstruct_keys(nil)

assert ([:receiver, :method, :label, :expected, :actual, :children] - result.keys).empty?
end

test "can be pattern matched" do
Age.new(17)
rescue Literal::TypeError => error
Comment on lines +32 to +34

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another way you could do this is

error = assert_raises(Literal::TypeError) do
  Age.new(17)
end

And then you can continue to make assertions about the error variable.

case error
in expected: expected_type, actual: (..17) => actual_value, children: [{ label: child_label, expected: child_expected, actual: child_actual }]
assert_equal expected_type.class, Literal::Types::ConstraintType
assert_equal actual_value, 17
assert_equal child_label, "_Constraint(Integer, 18..)"
assert_equal child_expected, (18..)
assert_equal child_actual, 17
end
end
Loading