From 976cb487ac2a6cbfa087c3164122a48acc85b743 Mon Sep 17 00:00:00 2001 From: Daniel Pepper Date: Sat, 3 Oct 2026 22:02:01 -0700 Subject: [PATCH 1/4] Keep Faker::Json width when generated keys collide build_shallow_hash assigned `width` times into a hash, so a repeated key (two equal first names) silently produced fewer than `width` entries in shallow_json and every level of add_depth_to_json. Retry on duplicates, bounded so a key generator with fewer than `width` values can't loop. This is what makes test_nested_json_length fail when the random stream lands on a duplicate name. Co-Authored-By: Claude Opus 5.5 --- lib/faker/default/json.rb | 6 +++++- test/faker/default/test_faker_json.rb | 10 ++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/faker/default/json.rb b/lib/faker/default/json.rb index 8edf1a9948..db921f13f2 100644 --- a/lib/faker/default/json.rb +++ b/lib/faker/default/json.rb @@ -86,7 +86,11 @@ def build_shallow_hash(width, options) value = options[:value] hash = {} - width.times do + # Retry on duplicate keys, bounded for key generators with fewer than + # `width` distinct values. + (width * 10).times do + break if hash.size == width + hash[eval(key)] = eval(value) end hash diff --git a/test/faker/default/test_faker_json.rb b/test/faker/default/test_faker_json.rb index a768329a2f..95e7f009cb 100644 --- a/test/faker/default/test_faker_json.rb +++ b/test/faker/default/test_faker_json.rb @@ -1,10 +1,20 @@ # frozen_string_literal: true +require 'minitest/mock' require_relative '../../test_helper' class TestFakerJson < Test::Unit::TestCase require 'json' + def test_shallow_json_keeps_width_when_keys_collide + # Seed 0 draws the same boolean key twice in a row. + Faker::Config.stub :random, Random.new(0) do + json = Faker::Json.shallow_json(width: 2, options: { key: 'Boolean.boolean', value: 'Boolean.boolean' }) + + assert_equal 2, JSON.parse(json).size + end + end + def test_simple_json_lenght expected_result_length = JSON.parse(simple_json).flatten.length From 53916830ac3a439ee41aa04c7ef60ac7a44ed2f5 Mon Sep 17 00:00:00 2001 From: Daniel Pepper Date: Sun, 4 Oct 2026 14:09:01 -0700 Subject: [PATCH 2/4] Apply suggestion from @dpep --- test/faker/default/test_faker_json.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/test/faker/default/test_faker_json.rb b/test/faker/default/test_faker_json.rb index 95e7f009cb..9bb0733569 100644 --- a/test/faker/default/test_faker_json.rb +++ b/test/faker/default/test_faker_json.rb @@ -7,7 +7,6 @@ class TestFakerJson < Test::Unit::TestCase require 'json' def test_shallow_json_keeps_width_when_keys_collide - # Seed 0 draws the same boolean key twice in a row. Faker::Config.stub :random, Random.new(0) do json = Faker::Json.shallow_json(width: 2, options: { key: 'Boolean.boolean', value: 'Boolean.boolean' }) From 3e48b733314d1cd6db14649c242c8299556886c4 Mon Sep 17 00:00:00 2001 From: Daniel Pepper Date: Sun, 4 Oct 2026 14:09:43 -0700 Subject: [PATCH 3/4] Apply suggestion from @dpep --- lib/faker/default/json.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/faker/default/json.rb b/lib/faker/default/json.rb index db921f13f2..49af4842e7 100644 --- a/lib/faker/default/json.rb +++ b/lib/faker/default/json.rb @@ -87,7 +87,6 @@ def build_shallow_hash(width, options) hash = {} # Retry on duplicate keys, bounded for key generators with fewer than - # `width` distinct values. (width * 10).times do break if hash.size == width From ec4814c1cfe2664508191005525ab0bd4bf03cd7 Mon Sep 17 00:00:00 2001 From: Daniel Pepper Date: Sun, 4 Oct 2026 14:10:09 -0700 Subject: [PATCH 4/4] Apply suggestion from @dpep --- lib/faker/default/json.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/faker/default/json.rb b/lib/faker/default/json.rb index 49af4842e7..6b0dad5c0f 100644 --- a/lib/faker/default/json.rb +++ b/lib/faker/default/json.rb @@ -86,7 +86,7 @@ def build_shallow_hash(width, options) value = options[:value] hash = {} - # Retry on duplicate keys, bounded for key generators with fewer than + # retry on duplicate (width * 10).times do break if hash.size == width