module ChefSpec::Extensions::Chef::Resource::ClassMethods

def action(sym, description: nil, &block)

def action(sym, description: nil, &block)
  inject_actions(sym)
  super(sym, &block)
end

def allowed_actions(*actions)

def allowed_actions(*actions)
  inject_actions(*actions) unless actions.empty?
  super
end

def allowed_actions=(value)

def allowed_actions=(value)
  inject_actions(*Array(value))
  super
end

def inject_actions(*actions)

def inject_actions(*actions)
  provides_names.each do |resource_name|
    next unless resource_name
    ChefSpec.define_matcher(resource_name)
    actions.each do |action|
      inject_method(:"#{action}_#{resource_name}", resource_name, action)
      if action == :create_if_missing
        inject_method(:"create_#{resource_name}_if_missing", resource_name, action)
      end
    end
  end
end

def inject_method(method, resource_name, action)

def inject_method(method, resource_name, action)
  unless ChefSpec::API.respond_to?(method)
    ChefSpec::API.send(:define_method, method) do |name|
      ChefSpec::Matchers::ResourceMatcher.new(resource_name, action, name)
    end
  end
end

def provides(name, **options, &block)

def provides(name, **options, &block)
  provides_names << name unless provides_names.include?(name)
  inject_actions(*allowed_actions)
  super
end

def provides_names

XXX: kind of a crappy way to find all the names of a resource
def provides_names
  @provides_names ||= []
end

def resource_name(name = ::Chef::NOT_PASSED)

def resource_name(name = ::Chef::NOT_PASSED)
  unless name == ::Chef::NOT_PASSED
    provides_names << name unless provides_names.include?(name)
    inject_actions(*allowed_actions)
  end
  super
end