require "support/shared/integration/integration_helper" describe "Resource.load_current_value" do include IntegrationSupport module Namer extend self attr_accessor :current_index def incrementing_value @incrementing_value += 1 @incrementing_value end attr_writer :incrementing_value end before(:all) { Namer.current_index = 1 } before { Namer.current_index += 1 } before { Namer.incrementing_value = 0 } let(:resource_name) { :"load_current_value_dsl#{Namer.current_index}" } let(:resource_class) do result = Class.new(Chef::Resource) do def self.to_s; resource_name.to_s; end def self.inspect; resource_name.inspect; end property :x, default: lazy { "default #{Namer.incrementing_value}" } def self.created_x=(value) @created = value end def self.created_x @created end action :create do new_resource.class.created_x = new_resource.x end end result.resource_name resource_name result end # Pull on resource_class to initialize it before { resource_class } context "with a resource with load_current_value" do before :each do resource_class.load_current_value do x "loaded #{Namer.incrementing_value} (#{self.class.properties.sort_by { |name, p| name } .select { |name, p| p.is_set?(self) } .map { |name, p| "#{name}=#{p.get(self)}" } .join(", ")})" end end context "and a resource with x set to a desired value" do let(:resource) do e = self r = nil converge do r = public_send(e.resource_name, "blah") do x "desired" end end r end it "current_resource is passed name but not x" do expect(resource.current_value.x).to eq "loaded 2 (name=blah)" end it "resource.current_value returns a different resource" do expect(resource.current_value.x).to eq "loaded 2 (name=blah)" expect(resource.x).to eq "desired" end it "resource.current_value constructs the resource anew each time" do expect(resource.current_value.x).to eq "loaded 2 (name=blah)" expect(resource.current_value.x).to eq "loaded 3 (name=blah)" end it "the provider accesses the current value of x" do expect(resource.class.created_x).to eq "desired" end context "and identity: :i and :d with desired_state: false" do before do resource_class.class_eval do property :i, identity: true property :d, desired_state: false end end before do resource.i "desired_i" resource.d "desired_d" end it "i, name and d are passed to load_current_value, but not x" do expect(resource.current_value.x).to eq "loaded 2 (d=desired_d, i=desired_i, name=blah)" end end context "and name_property: :i and :d with desired_state: false" do before do resource_class.class_eval do property :i, name_property: true property :d, desired_state: false end end before do resource.i "desired_i" resource.d "desired_d" end it "i, name and d are passed to load_current_value, but not x" do expect(resource.current_value.x).to eq "loaded 2 (d=desired_d, i=desired_i, name=blah)" end end end let (:subresource_name) do :"load_current_value_subresource_dsl#{Namer.current_index}" end let (:subresource_class) do r = Class.new(resource_class) do property :y, default: lazy { "default_y #{Namer.incrementing_value}" } end r.resource_name subresource_name r end # Pull on subresource_class to initialize it before { subresource_class } let(:subresource) do e = self r = nil converge do r = public_send(e.subresource_name, "blah") do x "desired" end end r end context "and a child resource class with no load_current_value" do it "the parent load_current_value is used" do expect(subresource.current_value.x).to eq "loaded 2 (name=blah)" end it "load_current_value yields a copy of the child class" do expect(subresource.current_value).to be_kind_of(subresource_class) end end context "And a child resource class with load_current_value" do before do subresource_class.load_current_value do y "loaded_y #{Namer.incrementing_value} (#{self.class.properties.sort_by { |name, p| name }. select { |name, p| p.is_set?(self) }. map { |name, p| "#{name}=#{p.get(self)}" }. join(", ")})" end end it "the overridden load_current_value is used" do current_resource = subresource.current_value expect(current_resource.x).to eq "default 3" expect(current_resource.y).to eq "loaded_y 2 (name=blah)" end end context "and a child resource class with load_current_value calling super()" do before do subresource_class.load_current_value do super() y "loaded_y #{Namer.incrementing_value} (#{self.class.properties.sort_by { |name, p| name }. select { |name, p| p.is_set?(self) }. map { |name, p| "#{name}=#{p.get(self)}" }. join(", ")})" end end it "the original load_current_value is called as well as the child one" do current_resource = subresource.current_value expect(current_resource.x).to eq "loaded 3 (name=blah)" expect(current_resource.y).to eq "loaded_y 4 (name=blah, x=loaded 3 (name=blah))" end end end end