200 lines
4.3 KiB
Ruby
200 lines
4.3 KiB
Ruby
# Copyright (c) HashiCorp, Inc.
|
|
# SPDX-License-Identifier: BUSL-1.1
|
|
|
|
require File.expand_path("../../../../base", __FILE__)
|
|
|
|
describe Vagrant::Action::Builtin::Call do
|
|
let(:app) { lambda { |env| } }
|
|
let(:env) { {} }
|
|
|
|
def wrapper_proc(data)
|
|
Class.new do
|
|
def initialize(app, env)
|
|
@app = app
|
|
end
|
|
|
|
def self.name
|
|
"TestAction"
|
|
end
|
|
|
|
define_method(:call) do |env|
|
|
env[:data] << "#{data}_in"
|
|
@app.call(env)
|
|
env[:data] << "#{data}_out"
|
|
end
|
|
end
|
|
end
|
|
|
|
it "should yield the env to the block" do
|
|
received = nil
|
|
|
|
callable = lambda do |env|
|
|
env[:result] = "value"
|
|
end
|
|
|
|
described_class.new(app, env, callable) do |env, builder|
|
|
received = env[:result]
|
|
end.call({})
|
|
|
|
expect(received).to eq("value")
|
|
end
|
|
|
|
it "should update the original env with any changes" do
|
|
callable = lambda { |env| }
|
|
next_step = lambda { |env| env[:inner] = true }
|
|
|
|
described_class.new(app, env, callable) do |_env, builder|
|
|
builder.use next_step
|
|
end.call(env)
|
|
|
|
expect(env[:inner]).to eq(true)
|
|
end
|
|
|
|
it "should call the callable with the original environment" do
|
|
received = nil
|
|
callable = lambda { |env| received = env[:foo] }
|
|
|
|
described_class.new(app, env, callable) do |_env, _builder|
|
|
# Nothing.
|
|
end.call({ foo: :bar })
|
|
|
|
expect(received).to eq(:bar)
|
|
end
|
|
|
|
it "should call the next builder" do
|
|
received = nil
|
|
callable = lambda { |env| }
|
|
next_step = lambda { |env| received = "value" }
|
|
|
|
described_class.new(app, env, callable) do |_env, builder|
|
|
builder.use next_step
|
|
end.call({})
|
|
|
|
expect(received).to eq("value")
|
|
end
|
|
|
|
it "should call the next builder with the original environment" do
|
|
received = nil
|
|
callable = lambda { |env| }
|
|
next_step = lambda { |env| received = env[:foo] }
|
|
|
|
described_class.new(app, env, callable) do |_env, builder|
|
|
builder.use next_step
|
|
end.call({ foo: :bar })
|
|
|
|
expect(received).to eq(:bar)
|
|
end
|
|
|
|
it "should call the next builder inserted in our own stack" do
|
|
callable = lambda { |env| }
|
|
|
|
builder = Vagrant::Action::Builder.new.tap do |b|
|
|
b.use wrapper_proc(1)
|
|
b.use described_class, callable do |_env, b2|
|
|
b2.use wrapper_proc(2)
|
|
end
|
|
b.use wrapper_proc(3)
|
|
end
|
|
|
|
env = { data: [] }
|
|
builder.call(env)
|
|
expect(env[:data]).to eq([
|
|
"1_in", "2_in", "3_in", "3_out", "2_out", "1_out"])
|
|
end
|
|
|
|
it "should instantiate the callable with the extra args" do
|
|
env = {}
|
|
|
|
callable = Class.new do
|
|
def initialize(app, env, arg)
|
|
env[:arg] = arg
|
|
end
|
|
|
|
def self.name
|
|
"TestAction"
|
|
end
|
|
|
|
def call(env); end
|
|
end
|
|
|
|
result = nil
|
|
instance = described_class.new(app, env, callable, :foo) do |inner_env, _builder|
|
|
result = inner_env[:arg]
|
|
end
|
|
instance.call(env)
|
|
|
|
expect(result).to eq(:foo)
|
|
end
|
|
|
|
it "should call the recover method for the sequence in an error" do
|
|
# Basic variables
|
|
callable = lambda { |env| }
|
|
|
|
# Build the steps for the test
|
|
basic_step = Class.new do
|
|
def initialize(app, env)
|
|
@app = app
|
|
@env = env
|
|
end
|
|
|
|
def self.name
|
|
"TestAction"
|
|
end
|
|
|
|
def call(env)
|
|
@app.call(env)
|
|
end
|
|
end
|
|
|
|
step_a = Class.new(basic_step) do
|
|
def call(env)
|
|
env[:steps] << :call_A
|
|
super
|
|
end
|
|
|
|
def self.name
|
|
"TestAction"
|
|
end
|
|
|
|
def recover(env)
|
|
env[:steps] << :recover_A
|
|
end
|
|
end
|
|
|
|
step_b = Class.new(basic_step) do
|
|
def call(env)
|
|
env[:steps] << :call_B
|
|
super
|
|
end
|
|
|
|
def self.name
|
|
"TestAction"
|
|
end
|
|
|
|
def recover(env)
|
|
env[:steps] << :recover_B
|
|
end
|
|
end
|
|
|
|
instance = described_class.new(app, env, callable) do |_env, builder|
|
|
builder.use step_a
|
|
builder.use step_b
|
|
end
|
|
|
|
env[:steps] = []
|
|
instance.call(env)
|
|
instance.recover(env)
|
|
|
|
expect(env[:steps]).to eq([:call_A, :call_B, :recover_B, :recover_A])
|
|
end
|
|
|
|
it "should recover even if it failed in the callable" do
|
|
callable = lambda { |env| raise "error" }
|
|
|
|
instance = described_class.new(app, env, callable) { |_env, _builder| }
|
|
instance.call(env) rescue nil
|
|
expect { instance.recover(env) }.
|
|
to_not raise_error
|
|
end
|
|
end
|