AaronLasseigne / active_interaction

:briefcase: Manage application specific business logic.
MIT License
2.06k stars 136 forks source link

Array Filter with default values aren't initialized on each run #562

Closed ScotterC closed 1 year ago

ScotterC commented 1 year ago

This is surprising behavior to me but maybe my mental model is off. When setting a default value for an array, such as an empty array, it maintains state of that array between separate calls to the interaction. In the below example, I would expect each run to have a responses length of 1 since it is adding to an empty array each time.

In a different scenario, with an array with default values, I'd expect those values to be initialized each time the interaction is run as well.

# /interactions/test_array.rb
class TestArray < ActiveInteraction::Base
  array :responses, default: []

  def execute
    responses << options.sample
  end

  def options
    ["one", "two", "three"]
  end
end

# /spec/interactions/test_array_spec.rb
RSpec.describe TestArray, type: :interaction do
  let(:outcome) { described_class.run }
  let(:result) { outcome.result }
  let(:errors) { outcome.errors }

  describe "#execute" do
    it "adds a random option to the responses array" do
      expect(outcome.options).to include(result.first)
    end

    it "initializes default on each run" do
      run_a = described_class.run
      expect(run_a.responses.length).to eq 1 #=> 2
      run_b = described_class.run
      expect(run_b.responses.length).to eq 1 #=> 3
    end
  end
end
AaronLasseigne commented 1 year ago

Defaults are processed when the file is loaded. If you want it to be initialized each time put it in a lambda.

array :responses, default: -> { [] }
ScotterC commented 1 year ago

🤦:) Glad there’s already docs in place! I’ll go try reading them.