# frozen_string_literal: true require 'rspec/matchers/built_in/count_expectation' module RSpec module Terraform module Matchers class IncludeResourceChange include RSpec::Matchers::BuiltIn::CountExpectation attr_reader :definition def initialize(definition = {}) @definition = definition @attributes = [] end def matches?(plan) matches = attribute_matches(plan) match_count = matches.count if has_expected_count? expected_count_matches?(match_count) else match_count.positive? end end def with_attribute_value(*args) stage, path, value = args.count == 3 ? args : [:after, *args] path = [path] if path.is_a?(Symbol) @attributes << { stage: stage, path: path, value: value } self end private def definition_matches(plan) plan.resource_changes_matching(definition) end def attribute_matches(plan) definition_matches(plan).filter do |resource_change| change = resource_change.change after = change.after_object @attributes.all? do |attribute| expected = RubyTerraform::Models::Objects.box(attribute[:value]) actual = after.dig(*attribute[:path]) actual == expected end end end end end end end # RSpec::Matchers.define :include_resource_creation do |type| # match do |plan| # resource_changes = plan.resource_changes_with_type(type) # resource_creations = resource_changes.filter(&:create?) # # return false if @count && resource_creations.length != @count # return false if resource_creations.empty? # # pp plan.to_h # # if @arguments # return resource_creations.any? do |resource_creation| # @arguments.all? do |name, value| # resource_creation.change.after[name] == value # end # end # end # # return true # end # # chain :count do |count| # @count = count # end # # chain :with_argument_value do |name, value| # @arguments = (@arguments || {}).merge(name => value) # end # # failure_message do |plan| # resource_creations = plan.resource_creations.map do |resource_creation| # "#{resource_creation.type}.#{resource_creation.name}" # end # "\nexpected: a plan with a resource creation for type: #{type}" \ # "\n got: a plan with resource creations:" \ # "\n - #{resource_creations.join("\n - ")}" # end # # failure_message_when_negated do |plan| # resource_creations = plan.resource_creations.map do |resource_creation| # "#{resource_creation.type}.#{resource_creation.name}" # end # "\nexpected: a plan without a resource creation for type: #{type}" \ # "\n got: a plan with resource creations:" \ # "\n - #{resource_creations.join("\n - ")}" # end # end