From 2eadfa2668a8de35da1d0a5591dd34daa8d9ea22 Mon Sep 17 00:00:00 2001 From: sergioperezcheco Date: Fri, 16 Oct 2026 11:21:34 +0800 Subject: [PATCH] fix: preserve computed dependency argument order Bind computed arguments in declared dependency order and preserve false and nil slots without changing evaluation order. Add regression coverage for shared dependencies, forward references, and false/nil values. Assisted-by: OpenAI gpt-6.1-sol via Hermes Agent Signed-off-by: sergioperezcheco --- lib/helpers/positional_generator.rb | 4 +- test/helpers/test_positional_generator.rb | 47 +++++++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 test/helpers/test_positional_generator.rb diff --git a/lib/helpers/positional_generator.rb b/lib/helpers/positional_generator.rb index d81a2e754a..6dc99e44b2 100644 --- a/lib/helpers/positional_generator.rb +++ b/lib/helpers/positional_generator.rb @@ -322,8 +322,8 @@ def generate_values(stack) component = @components[component_id] raise if component.nil? - values = result.filter_map do |(_id, name, value)| - value if component.deps.include?(name) + values = component.deps.map do |dependency| + result.find { |(_id, name, _value)| name == dependency }.last end result << [component.position, component.name, component.generator.generate(values)] diff --git a/test/helpers/test_positional_generator.rb b/test/helpers/test_positional_generator.rb new file mode 100644 index 0000000000..6a844f8585 --- /dev/null +++ b/test/helpers/test_positional_generator.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +require_relative '../test_helper' + +class TestPositionalGenerator < Test::Unit::TestCase + def test_computed_dependencies_follow_declared_order + generated = Faker::Base.generate(:string) do |g| + g.lit('2', name: :left) + g.lit('7', name: :right) + g.computed(deps: %i[right left]) { |right, left| right.to_i - left.to_i } + end + + assert_equal('275', generated) + end + + def test_computed_dependencies_follow_declared_order_with_forward_references + generated = Faker::Base.generate(:string) do |g| + g.computed(deps: %i[right left]) { |right, left| right.to_i - left.to_i } + g.lit('2', name: :left) + g.lit('7', name: :right) + end + + assert_equal('527', generated) + end + + def test_shared_dependencies_follow_each_computations_order + generated = Faker::Base.generate(:string) do |g| + g.lit('2', name: :left) + g.lit('7', name: :right) + g.computed(deps: %i[left right]) { |left, right| left.to_i - right.to_i } + g.computed(deps: %i[right left]) { |right, left| right.to_i - left.to_i } + end + + assert_equal('27-55', generated) + end + + def test_computed_dependencies_keep_false_and_nil_values + generated = Faker::Base.generate(:string) do |g| + g.computed(name: :flag) { false } + g.computed(name: :empty) { nil } + g.lit('end', name: :last) + g.computed(deps: %i[flag empty last]) { |*values| values.inspect } + end + + assert_equal('falseend[false, nil, "end"]', generated) + end +end