Skip to content
Merged
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
10 changes: 9 additions & 1 deletion ext/json/ext/parser/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -2021,7 +2021,15 @@ static int parser_config_init_i(VALUE key, VALUE val, VALUE data)
else if (key == sym_allow_invalid_escape) { config->allow_invalid_escape = RTEST(val); }
else if (key == sym_symbolize_names) { config->symbolize_names = RTEST(val); }
else if (key == sym_freeze) { config->freeze = RTEST(val); }
else if (key == sym_on_load) { parser_config_wb_write(self, &config->on_load_proc, RTEST(val) ? val : Qfalse); }
else if (key == sym_on_load) {
if (RTEST(val) && !rb_obj_is_proc(val)) {
val = rb_check_funcall(val, rb_intern("to_proc"), 0, NULL);
if (val == Qundef || !rb_obj_is_proc(val)) {
rb_raise(rb_eTypeError, "on_load must be a Proc");
}
}
parser_config_wb_write(self, &config->on_load_proc, RTEST(val) ? val : Qfalse);
}
else if (key == sym_allow_duplicate_key) { config->allow_duplicate_key = RTEST(val); }
else if (key == sym_decimal_class) {
if (RTEST(val)) {
Expand Down
10 changes: 10 additions & 0 deletions test/json/json_coder_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,16 @@ def test_json_coder_load_options
assert_equal({a: 1}, coder.load('{"a":1}'))
end

def test_json_coder_load_with_on_load_method
on_load = ->(value) { Integer === value ? value + 1 : value }.method(:call)
coder = JSON::Coder.new(on_load: on_load)
assert_equal [2], coder.load('[1]')
end

def test_json_coder_on_load_invalid_type
assert_raise(TypeError) { JSON::Coder.new(on_load: 'x') }
end

def test_json_coder_dump_NaN_or_Infinity
coder = JSON::Coder.new { |o| o.inspect }
assert_equal "NaN", coder.load(coder.dump(Float::NAN))
Expand Down
26 changes: 26 additions & 0 deletions test/json/json_parser_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,32 @@ def test_parsing
assert_equal 'test', parser.parse
end

def test_on_load_method
on_load = ->(value) { Integer === value ? value + 1 : value }.method(:call)
assert_equal [2], JSON.parse('[1]', on_load: on_load)
end

def test_on_load_invalid_type
['x', Object.new, Time.now].each do |on_load|
assert_raise(TypeError) { JSON.parse('[1]', on_load: on_load) }
end
end

def test_on_load_invalid_to_proc
on_load = Object.new
def on_load.to_proc
method(:to_proc)
end
assert_raise(TypeError) { JSON.parse('[1]', on_load: on_load) }
end

def test_on_load_falsy
[nil, false].each do |on_load|
config = JSON::Parser::Config.new(on_load: on_load)
assert_equal [1], config.parse('[1]')
end
end

def test_parser_reset
parser = Parser.new('{"a":"b"}')
assert_equal({ 'a' => 'b' }, parser.parse)
Expand Down
8 changes: 8 additions & 0 deletions test/json/resumable_parser_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,14 @@ def test_nested_parse_error
end
end

def test_on_load_method
on_load = ->(value) { Integer === value ? value + 1 : value }.method(:call)
parser = new_parser(on_load: on_load)
parser << '[1]'
assert parser.parse
assert_equal [2], parser.value
end

def test_parse_document_direct
@parser << '[true]'
assert_equal true, @parser.parse
Expand Down
Loading