Skip to content

Commit 43f6fc6

Browse files
authored
Merge pull request #725 from Shopify/fix-ruby-3.5-sets
Handle Ruby 3.5 new Set class
2 parents 7497040 + c2d185d commit 43f6fc6

File tree

3 files changed

+91
-41
lines changed

3 files changed

+91
-41
lines changed

lib/psych/core_ext.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,17 @@ def to_yaml options = {}
1717
if defined?(::IRB)
1818
require_relative 'y'
1919
end
20+
21+
22+
# TODO: how best to check for builtin Set?
23+
if defined?(::Set) && Object.const_source_location(:Set) == ["ruby", 0]
24+
class Set
25+
def encode_with(coder)
26+
coder["hash"] = to_h
27+
end
28+
29+
def init_with(coder)
30+
replace(coder["hash"].keys)
31+
end
32+
end
33+
end

test/psych/test_psych_set.rb

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# frozen_string_literal: true
2+
require_relative 'helper'
3+
4+
module Psych
5+
class TestPsychSet < TestCase
6+
def setup
7+
super
8+
@set = Psych::Set.new
9+
@set['foo'] = 'bar'
10+
@set['bar'] = 'baz'
11+
end
12+
13+
def test_dump
14+
assert_match(/!set/, Psych.dump(@set))
15+
end
16+
17+
def test_roundtrip
18+
assert_cycle(@set)
19+
end
20+
21+
###
22+
# FIXME: Syck should also support !!set as shorthand
23+
def test_load_from_yaml
24+
loaded = Psych.unsafe_load(<<-eoyml)
25+
--- !set
26+
foo: bar
27+
bar: baz
28+
eoyml
29+
assert_equal(@set, loaded)
30+
end
31+
32+
def test_loaded_class
33+
assert_instance_of(Psych::Set, Psych.unsafe_load(Psych.dump(@set)))
34+
end
35+
36+
def test_set_shorthand
37+
loaded = Psych.unsafe_load(<<-eoyml)
38+
--- !!set
39+
foo: bar
40+
bar: baz
41+
eoyml
42+
assert_instance_of(Psych::Set, loaded)
43+
end
44+
45+
def test_set_self_reference
46+
@set['self'] = @set
47+
assert_cycle(@set)
48+
end
49+
50+
def test_stringify_names
51+
@set[:symbol] = :value
52+
53+
assert_match(/^:symbol: :value/, Psych.dump(@set))
54+
assert_match(/^symbol: :value/, Psych.dump(@set, stringify_names: true))
55+
end
56+
end
57+
end

test/psych/test_set.rb

Lines changed: 20 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,36 @@
1+
# encoding: UTF-8
12
# frozen_string_literal: true
23
require_relative 'helper'
4+
require 'set' unless defined?(Set)
35

46
module Psych
57
class TestSet < TestCase
68
def setup
7-
super
8-
@set = Psych::Set.new
9-
@set['foo'] = 'bar'
10-
@set['bar'] = 'baz'
9+
@set = ::Set.new([1, 2, 3])
1110
end
1211

1312
def test_dump
14-
assert_match(/!set/, Psych.dump(@set))
13+
assert_equal <<~YAML, Psych.dump(@set)
14+
--- !ruby/object:Set
15+
hash:
16+
1: true
17+
2: true
18+
3: true
19+
YAML
1520
end
1621

17-
def test_roundtrip
18-
assert_cycle(@set)
19-
end
20-
21-
###
22-
# FIXME: Syck should also support !!set as shorthand
23-
def test_load_from_yaml
24-
loaded = Psych.unsafe_load(<<-eoyml)
25-
--- !set
26-
foo: bar
27-
bar: baz
28-
eoyml
29-
assert_equal(@set, loaded)
22+
def test_load
23+
assert_equal @set, Psych.load(<<~YAML, permitted_classes: [::Set])
24+
--- !ruby/object:Set
25+
hash:
26+
1: true
27+
2: true
28+
3: true
29+
YAML
3030
end
3131

32-
def test_loaded_class
33-
assert_instance_of(Psych::Set, Psych.unsafe_load(Psych.dump(@set)))
34-
end
35-
36-
def test_set_shorthand
37-
loaded = Psych.unsafe_load(<<-eoyml)
38-
--- !!set
39-
foo: bar
40-
bar: baz
41-
eoyml
42-
assert_instance_of(Psych::Set, loaded)
43-
end
44-
45-
def test_set_self_reference
46-
@set['self'] = @set
47-
assert_cycle(@set)
48-
end
49-
50-
def test_stringify_names
51-
@set[:symbol] = :value
52-
53-
assert_match(/^:symbol: :value/, Psych.dump(@set))
54-
assert_match(/^symbol: :value/, Psych.dump(@set, stringify_names: true))
32+
def test_roundtrip
33+
assert_equal @set, Psych.load(Psych.dump(@set), permitted_classes: [::Set])
5534
end
5635
end
5736
end

0 commit comments

Comments
 (0)