Skip to content

Commit

Permalink
json_pure: fix ractor compatibility
Browse files Browse the repository at this point in the history
This actually never worked, because the test was always testing
the ext version from the stdlib, never the pure version nor the
current ext version.
  • Loading branch information
byroot committed Oct 25, 2024
1 parent 7fd3531 commit e285489
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 23 deletions.
29 changes: 15 additions & 14 deletions lib/json/pure/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -148,25 +148,26 @@ def convert_encoding(source)
end

# Unescape characters in strings.
UNESCAPE_MAP = Hash.new { |h, k| h[k] = k.chr }
UNESCAPE_MAP.update({
?" => '"',
?\\ => '\\',
?/ => '/',
?b => "\b",
?f => "\f",
?n => "\n",
?r => "\r",
?t => "\t",
?u => nil,
})
# UNESCAPE_MAP = Hash.new { |h, k| puts; p [:k, k]; h[k] = k.chr }
UNESCAPE_MAP = {
'"' => '"',
'\\' => '\\',
'/' => '/',
'b' => "\b",
'f' => "\f",
'n' => "\n",
'r' => "\r",
't' => "\t",
'u' => nil,
}.freeze

STR_UMINUS = ''.respond_to?(:-@)
def parse_string
if scan(STRING)
return '' if self[1].empty?
string = self[1].gsub(%r((?:\\[\\bfnrt"/]|(?:\\u(?:[A-Fa-f\d]{4}))+|\\[\x20-\xff]))n) do |c|
if u = UNESCAPE_MAP[$&[1]]
string = self[1].gsub(%r{(?:\\[\\bfnrt"/]|(?:\\u(?:[A-Fa-f\d]{4}))+|\\[\x20-\xff])}n) do |c|
k = $&[1]
if u = UNESCAPE_MAP.fetch(k) { k.chr }
u
else # \uXXXX
bytes = ''.b
Expand Down
28 changes: 19 additions & 9 deletions test/json/ractor_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@

class JSONInRactorTest < Test::Unit::TestCase
def test_generate
assert_separately(%w[-rjson -Ilib -Iext], "#{<<~"begin;"}\n#{<<~'end;'}", ignore_stderr: true)
begin;
$VERBOSE = nil
require "json"
pid = fork do
r = Ractor.new do
json = JSON.generate({
'a' => 2,
Expand All @@ -26,9 +23,22 @@ def test_generate
})
JSON.parse(json)
end
expected_json = '{"a":2,"b":3.141,"c":"c","d":[1,"b",3.14],"e":{"foo":"bar"},' +
'"g":"\\"\\u0000\\u001f","h":1000.0,"i":0.001}'
assert_equal(JSON.parse(expected_json), r.take)
end;
expected_json = JSON.parse('{"a":2,"b":3.141,"c":"c","d":[1,"b",3.14],"e":{"foo":"bar"},' +
'"g":"\\"\\u0000\\u001f","h":1000.0,"i":0.001}')
actual_json = r.take

if expected_json == actual_json
exit 0
else
puts "Expected:"
puts expected_json
puts "Acutual:"
puts actual_json
puts
exit 1
end
end
_, status = Process.waitpid2(pid)
assert_predicate status, :success?
end
end if defined?(Ractor)
end if defined?(Ractor) && Process.respond_to?(:fork)

0 comments on commit e285489

Please sign in to comment.