From e285489d55dce04fc354ea12da401879239692cd Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Fri, 25 Oct 2024 12:35:29 +0200 Subject: [PATCH] json_pure: fix ractor compatibility 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. --- lib/json/pure/parser.rb | 29 +++++++++++++++-------------- test/json/ractor_test.rb | 28 +++++++++++++++++++--------- 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/lib/json/pure/parser.rb b/lib/json/pure/parser.rb index 3dafe830..b5c2b1ba 100644 --- a/lib/json/pure/parser.rb +++ b/lib/json/pure/parser.rb @@ -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 diff --git a/test/json/ractor_test.rb b/test/json/ractor_test.rb index 646baddf..f857c9a8 100644 --- a/test/json/ractor_test.rb +++ b/test/json/ractor_test.rb @@ -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, @@ -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)