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
52 changes: 25 additions & 27 deletions java/src/json/ext/GeneratorState.java
Original file line number Diff line number Diff line change
Expand Up @@ -545,43 +545,41 @@ public IRubyObject _configure(ThreadContext context, IRubyObject vOpts) {
checkFrozen();
OptionsReader opts = new OptionsReader(context, vOpts);

ByteList indent = opts.getString("indent");
if (indent != null) this.indent = indent;

ByteList space = opts.getString("space");
if (space != null) this.space = space;

ByteList spaceBefore = opts.getString("space_before");
if (spaceBefore != null) this.spaceBefore = spaceBefore;

ByteList arrayNl = opts.getString("array_nl");
if (arrayNl != null) this.arrayNl = arrayNl;

this.asJSON = opts.getProc("as_json");

ByteList objectNl = opts.getString("object_nl");
if (objectNl != null) this.objectNl = objectNl;

maxNesting = opts.getInt("max_nesting", DEFAULT_MAX_NESTING);
allowNaN = opts.getBool("allow_nan", DEFAULT_ALLOW_NAN);
asciiOnly = opts.getBool("ascii_only", DEFAULT_ASCII_ONLY);
scriptSafe = opts.getBool("script_safe", DEFAULT_SCRIPT_SAFE);
strict = opts.getBool("strict", DEFAULT_STRICT);
bufferInitialLength = opts.getInt("buffer_initial_length", DEFAULT_BUFFER_INITIAL_LENGTH);

depth = opts.getInt("depth", 0);
this.indent = stringConfig(opts, "indent", this.indent);
this.space = stringConfig(opts, "space", this.space);
this.spaceBefore = stringConfig(opts, "space_before", this.spaceBefore);
this.arrayNl = stringConfig(opts, "array_nl", this.arrayNl);
this.objectNl = stringConfig(opts, "object_nl", this.objectNl);

if (opts.hasKey("as_json")) this.asJSON = opts.getProc("as_json");

maxNesting = opts.getInt("max_nesting", maxNesting);
allowNaN = opts.getBool("allow_nan", allowNaN);
asciiOnly = opts.getBool("ascii_only", asciiOnly);
scriptSafe = opts.getBool("script_safe", scriptSafe);
strict = opts.getBool("strict", strict);
bufferInitialLength = opts.getInt("buffer_initial_length", bufferInitialLength);

depth = opts.getInt("depth", depth);
if (depth < 0) {
throw context.runtime.newArgumentError("depth must be >= 0 (got: " + depth + ")");
}
this.allowDuplicateKey = opts.getBool("allow_duplicate_key", false);
this.allowDuplicateKey = opts.getBool("allow_duplicate_key", allowDuplicateKey);

sortKeys = normalizeSortKeys(context, opts.get("sort_keys"));
if (opts.hasKey("sort_keys")) sortKeys = normalizeSortKeys(context, opts.get("sort_keys"));

opts.ensureEmpty();

return this;
}

// A falsy value writes the empty string, as string_config() does in the C extension.
private static ByteList stringConfig(OptionsReader opts, String key, ByteList current) {
if (!opts.hasKey(key)) return current;
ByteList value = opts.getString(key);
return value == null ? ByteList.EMPTY_BYTELIST : value;
}

/**
* <code>State#to_h()</code>
*
Expand Down
20 changes: 17 additions & 3 deletions test/json/json_generator_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -539,18 +539,32 @@ def test_configure_keeps_the_layout_of_a_pretty_state
end

def test_configure_only_writes_the_other_options_it_is_given
omit 'JRuby resets the non-string options' if RUBY_ENGINE == 'jruby'
state = JSON.state.new(max_nesting: 3, allow_nan: true, ascii_only: true, script_safe: true)
state = JSON.state.new(max_nesting: 3, allow_nan: true, ascii_only: true, script_safe: true,
strict: true, buffer_initial_length: 32)
state.configure(indent: '1')
assert_equal '1', state.indent
assert_equal 3, state.max_nesting
assert_equal true, state.allow_nan?
assert_equal true, state.ascii_only?
assert_equal true, state.script_safe?
assert_equal true, state.strict?
assert_equal 32, state.buffer_initial_length
end

def test_configure_keeps_sort_keys
state = JSON.state.new(sort_keys: true)
state.configure(depth: 0)
assert_equal '{"a":2,"b":1}', state.generate({ 'b' => 1, 'a' => 2 })
end

def test_configure_keeps_as_json
as_json = ->(object, _is_key) { object.to_s }
state = JSON.state.new(strict: true, as_json: as_json)
state.configure(depth: 0)
assert_equal as_json, state.as_json
end

def test_configure_writes_a_string_option_given_as_nil
omit 'JRuby keeps the previous value for an explicit nil' if RUBY_ENGINE == 'jruby'
state = JSON.state.new(indent: '1', space: '2')
state.configure(indent: nil)
assert_equal '', state.indent
Expand Down