Skip to content

Commit cf7e62c

Browse files
committed
🥅 Improve SequenceSet frozen errors
Previously, SequenceSet modification methods would raise a frozen error when it updated its internal data structure (currently implemented as an array of arrays), which was "can't modify frozen Array: [int, int]". This was unexpected, confusing, and misleading. This changes the SequenceSet modification methods to raise the expected FrozenError _prior_ to attempting to modify the internal data structure.
1 parent 2813b4c commit cf7e62c

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

lib/net/imap/sequence_set.rb

+9
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,7 @@ def add(object)
675675
# Unlike #add, #merge, or #union, the new value is appended to #string.
676676
# This may result in a #string which has duplicates or is out-of-order.
677677
def append(object)
678+
modifying!
678679
tuple = input_to_tuple object
679680
entry = tuple_to_str tuple
680681
tuple_add tuple
@@ -1310,6 +1311,12 @@ def intersect_tuple?((min, max))
13101311
range.include?(min) || range.include?(max) || (min..max).cover?(range)
13111312
end
13121313

1314+
def modifying!
1315+
if frozen?
1316+
raise FrozenError, "can't modify frozen #{self.class}: %p" % [self]
1317+
end
1318+
end
1319+
13131320
def tuples_add(tuples) tuples.each do tuple_add _1 end; self end
13141321
def tuples_subtract(tuples) tuples.each do tuple_subtract _1 end; self end
13151322

@@ -1324,6 +1331,7 @@ def tuples_subtract(tuples) tuples.each do tuple_subtract _1 end; self end
13241331
# ---------??===lower==|--|==|----|===upper===|-- join until upper
13251332
# ---------??===lower==|--|==|--|=====upper===|-- join to upper
13261333
def tuple_add(tuple)
1334+
modifying!
13271335
min, max = tuple
13281336
lower, lower_idx = tuple_gte_with_index(min - 1)
13291337
if lower.nil? then tuples << tuple
@@ -1360,6 +1368,7 @@ def tuple_coalesce(lower, lower_idx, min, max)
13601368
# -------??=====lower====|--|====|---|====upper====|-- 7. delete until
13611369
# -------??=====lower====|--|====|--|=====upper====|-- 8. delete and trim
13621370
def tuple_subtract(tuple)
1371+
modifying!
13631372
min, max = tuple
13641373
lower, idx = tuple_gte_with_index(min)
13651374
if lower.nil? then nil # case 1.

test/net/imap/test_sequence_set.rb

+26
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,32 @@ def compare_to_reference_set(nums, set, seqset)
5757
assert_equal set, set.freeze
5858
end
5959

60+
data "#clear", :clear
61+
data "#replace seq", ->{ _1.replace SequenceSet[1] }
62+
data "#replace num", ->{ _1.replace 1 }
63+
data "#replace str", ->{ _1.replace ?1 }
64+
data "#string=", ->{ _1.string = ?1 }
65+
data "#add", ->{ _1.add 1 }
66+
data "#add?", ->{ _1.add? 1 }
67+
data "#<<", ->{ _1 << 1 }
68+
data "#append", ->{ _1.append 1 }
69+
data "#delete", ->{ _1.delete 3 }
70+
data "#delete?", ->{ _1.delete? 3 }
71+
data "#delete_at", ->{ _1.delete_at 3 }
72+
data "#slice!", ->{ _1.slice! 1 }
73+
data "#merge", ->{ _1.merge 1 }
74+
data "#subtract", ->{ _1.subtract 1 }
75+
data "#limit!", ->{ _1.limit! max: 10 }
76+
data "#complement!", :complement!
77+
data "#normalize!", :normalize!
78+
test "frozen error message" do |modification|
79+
set = SequenceSet["2:4,7:11,99,999"]
80+
msg = "can't modify frozen Net::IMAP::SequenceSet: %p" % [set]
81+
assert_raise_with_message FrozenError, msg do
82+
modification.to_proc.(set)
83+
end
84+
end
85+
6086
%i[clone dup].each do |method|
6187
test "##{method}" do
6288
orig = SequenceSet.new "2:4,7:11,99,999"

0 commit comments

Comments
 (0)