mirror of
https://github.com/inspec/inspec
synced 2025-02-17 06:28:40 +00:00
Merge pull request #1076 from chef/ssd/issue-1074
Ensure resources are visible inside its blocks
This commit is contained in:
commit
178156499f
5 changed files with 107 additions and 18 deletions
|
@ -23,7 +23,7 @@ module Inspec
|
|||
require 'rspec/core/dsl'
|
||||
Class.new(Inspec::Rule) do
|
||||
include RSpec::Core::DSL
|
||||
include resources_dsl
|
||||
with_resource_dsl resources_dsl
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -128,10 +128,12 @@ module Inspec
|
|||
@rules.delete(full_id(@profile_id, id))
|
||||
end
|
||||
|
||||
attr_reader :current_load
|
||||
|
||||
def register_rule(r)
|
||||
# get the full ID
|
||||
r.instance_variable_set(:@__file, @current_load[:file])
|
||||
r.instance_variable_set(:@__group_title, @current_load[:title])
|
||||
r.instance_variable_set(:@__file, current_load[:file])
|
||||
r.instance_variable_set(:@__group_title, current_load[:title])
|
||||
|
||||
# add the rule to the registry
|
||||
fid = full_id(Inspec::Rule.profile_id(r), Inspec::Rule.rule_id(r))
|
||||
|
|
|
@ -12,6 +12,24 @@ module Inspec
|
|||
class Rule # rubocop:disable Metrics/ClassLength
|
||||
include ::RSpec::Matchers
|
||||
|
||||
#
|
||||
# Include any resources from the given resource DSL. The passed
|
||||
# resource_dsl will also be included in any Inspec::Expect objects
|
||||
# we make.
|
||||
#
|
||||
# @params resource_dsl [Module]
|
||||
# @returns [TrueClass]
|
||||
#
|
||||
def self.with_resource_dsl(resource_dsl)
|
||||
include resource_dsl
|
||||
@resource_dsl = resource_dsl
|
||||
true
|
||||
end
|
||||
|
||||
def self.resource_dsl # rubocop:disable Style/TrivialAccessors
|
||||
@resource_dsl
|
||||
end
|
||||
|
||||
def initialize(id, profile_id, _opts, &block)
|
||||
@impact = nil
|
||||
@title = nil
|
||||
|
@ -106,12 +124,12 @@ module Inspec
|
|||
include dsl
|
||||
end.new(method(:__add_check))
|
||||
else
|
||||
__add_check('describe', values, block)
|
||||
__add_check('describe', values, with_dsl(block))
|
||||
end
|
||||
end
|
||||
|
||||
def expect(value, &block)
|
||||
target = Inspec::Expect.new(value, &block)
|
||||
target = Inspec::Expect.new(value, &with_dsl(block))
|
||||
__add_check('expect', [value], target)
|
||||
target
|
||||
end
|
||||
|
@ -188,6 +206,31 @@ module Inspec
|
|||
@__checks.push([describe_or_expect, values, block])
|
||||
end
|
||||
|
||||
#
|
||||
# Takes a block and returns a block that will run the given block
|
||||
# with access to the resource_dsl of the current class. This is to
|
||||
# ensure that inside the constructed Rspec::ExampleGroup users
|
||||
# have access to DSL methods. Previous this was done in
|
||||
# Inspec::Runner before sending the example groups to rspec. It
|
||||
# was moved here to ensure that code inside `its` blocks hae the
|
||||
# same visibility into resources as code outside its blocks.
|
||||
#
|
||||
# @param [Proc] block
|
||||
# @return [Proc]
|
||||
#
|
||||
def with_dsl(block)
|
||||
return nil if block.nil?
|
||||
if self.class.resource_dsl
|
||||
dsl = self.class.resource_dsl
|
||||
proc do |*args|
|
||||
include dsl
|
||||
instance_exec(*args, &block)
|
||||
end
|
||||
else
|
||||
block
|
||||
end
|
||||
end
|
||||
|
||||
# Idio(ma)tic unindent
|
||||
# TODO: replace this
|
||||
#
|
||||
|
|
|
@ -229,21 +229,11 @@ module Inspec
|
|||
Inspec::Log.debug "Registering rule #{rule}"
|
||||
@rules << rule
|
||||
checks = ::Inspec::Rule.prepare_checks(rule)
|
||||
examples = checks.map do |m, a, b|
|
||||
examples = checks.flat_map do |m, a, b|
|
||||
get_check_example(m, a, b)
|
||||
end.flatten.compact
|
||||
end.compact
|
||||
|
||||
examples.each do |example|
|
||||
# TODO: Remove this!! It is very dangerous to do this here.
|
||||
# The goal of this is to make the audit DSL available to all
|
||||
# describe blocks. Right now, these blocks are executed outside
|
||||
# the scope of this run, thus not gaining ony of the DSL pieces.
|
||||
# To circumvent this, the full DSL is attached to the example's
|
||||
# scope.
|
||||
dsl = Inspec::Resource.create_dsl(backend)
|
||||
example.send(:include, dsl)
|
||||
@test_collector.add_test(example, rule)
|
||||
end
|
||||
examples.each { |e| @test_collector.add_test(e, rule) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
54
test/unit/profiles/control_eval_context_tests.rb
Normal file
54
test/unit/profiles/control_eval_context_tests.rb
Normal file
|
@ -0,0 +1,54 @@
|
|||
# encoding: utf-8
|
||||
# author: Steven Danna
|
||||
|
||||
require 'helper'
|
||||
require 'rspec/core'
|
||||
require 'inspec/control_eval_context'
|
||||
|
||||
describe Inspec::ControlEvalContext do
|
||||
module FakeDSL
|
||||
def foobar
|
||||
"wombat"
|
||||
end
|
||||
end
|
||||
Inspec::Log.level = :debug
|
||||
|
||||
let(:control_content) { <<EOF
|
||||
control 'foo' do
|
||||
describe foobar do
|
||||
end
|
||||
end
|
||||
|
||||
control 'bar' do
|
||||
describe "wombat" do
|
||||
it { should_equal foobar }
|
||||
end
|
||||
end
|
||||
EOF
|
||||
}
|
||||
|
||||
let(:resource_dsl) { FakeDSL }
|
||||
let(:backend) { mock() }
|
||||
let(:profile_context) { Inspec::ProfileContext.new('test-profile', backend, {}) }
|
||||
let(:eval_context) do
|
||||
c = Inspec::ControlEvalContext.create(profile_context, resource_dsl)
|
||||
# A lot of mocking here :(
|
||||
c.new(backend, mock(), mock(), mock())
|
||||
end
|
||||
|
||||
it 'accepts a context and a resource_dsl' do
|
||||
Inspec::ControlEvalContext.create(profile_context, resource_dsl)
|
||||
end
|
||||
|
||||
it 'provides rules with access to the given DSL' do
|
||||
profile_context.stubs(:current_load).returns({file: "<test content>"})
|
||||
eval_context.instance_eval(control_content)
|
||||
profile_context.all_rules.each do |rule|
|
||||
# Turn each rule into an example group and run it, none of the example content should raise an
|
||||
# exception
|
||||
Inspec::Rule.prepare_checks(rule).each do |m, a, b|
|
||||
RSpec::Core::ExampleGroup.describe(*a, &b).run
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Add table
Reference in a new issue