Merge Condition::DSL into Condition
This commit is contained in:
parent
2c335b2437
commit
3b28045340
@ -14,7 +14,7 @@ require 'producer/core/actions/file_append'
|
||||
require 'producer/core/actions/file_replace_content'
|
||||
require 'producer/core/actions/file_writer'
|
||||
|
||||
# condition tests (need to be defined before the condition DSL)
|
||||
# condition tests
|
||||
require 'producer/core/test'
|
||||
require 'producer/core/tests/condition_test'
|
||||
require 'producer/core/tests/file_contains'
|
||||
@ -27,7 +27,6 @@ require 'producer/core/tests/shell_command_status'
|
||||
|
||||
require 'producer/core/cli'
|
||||
require 'producer/core/condition'
|
||||
require 'producer/core/condition/dsl'
|
||||
require 'producer/core/env'
|
||||
require 'producer/core/errors'
|
||||
require 'producer/core/logger_formatter'
|
||||
|
@ -2,16 +2,45 @@ module Producer
|
||||
module Core
|
||||
class Condition
|
||||
class << self
|
||||
def define_test(keyword, test)
|
||||
{
|
||||
keyword => false,
|
||||
"no_#{keyword}" => true
|
||||
}.each do |kw, negated|
|
||||
define_method(kw) do |*args|
|
||||
if test.respond_to? :call
|
||||
args = [test, *args]
|
||||
klass = Tests::ConditionTest
|
||||
else
|
||||
klass = test
|
||||
end
|
||||
t = klass.new(@env, *args, negated: negated)
|
||||
@tests << t
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def evaluate(env, *args, &block)
|
||||
dsl = DSL.new(env, &block)
|
||||
return_value = dsl.evaluate *args
|
||||
Condition.new(dsl.tests, return_value)
|
||||
new.tap do |o|
|
||||
o.instance_eval { @env = env }
|
||||
return_value = o.instance_exec *args, &block
|
||||
o.instance_eval { @return_value = return_value }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
define_test :`, Tests::ShellCommandStatus
|
||||
define_test :sh, Tests::ShellCommandStatus
|
||||
define_test :file_contains, Tests::FileContains
|
||||
define_test :file_eq, Tests::FileEq
|
||||
define_test :env?, Tests::HasEnv
|
||||
define_test :executable?, Tests::HasExecutable
|
||||
define_test :dir?, Tests::HasDir
|
||||
define_test :file?, Tests::HasFile
|
||||
|
||||
attr_reader :tests, :return_value
|
||||
|
||||
def initialize(tests, return_value = nil)
|
||||
def initialize(tests = [], return_value = nil)
|
||||
@tests = tests
|
||||
@return_value = return_value
|
||||
end
|
||||
|
@ -1,48 +0,0 @@
|
||||
module Producer
|
||||
module Core
|
||||
class Condition
|
||||
class DSL
|
||||
class << self
|
||||
def define_test(keyword, test)
|
||||
{
|
||||
keyword => false,
|
||||
"no_#{keyword}" => true
|
||||
}.each do |kw, negated|
|
||||
define_method(kw) do |*args|
|
||||
if test.respond_to? :call
|
||||
args = [test, *args]
|
||||
klass = Tests::ConditionTest
|
||||
else
|
||||
klass = test
|
||||
end
|
||||
t = klass.new(@env, *args, negated: negated)
|
||||
@tests << t
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
define_test :`, Tests::ShellCommandStatus
|
||||
define_test :sh, Tests::ShellCommandStatus
|
||||
define_test :file_contains, Tests::FileContains
|
||||
define_test :file_eq, Tests::FileEq
|
||||
define_test :env?, Tests::HasEnv
|
||||
define_test :executable?, Tests::HasExecutable
|
||||
define_test :dir?, Tests::HasDir
|
||||
define_test :file?, Tests::HasFile
|
||||
|
||||
attr_reader :block, :env, :tests
|
||||
|
||||
def initialize(env, &block)
|
||||
@env = env
|
||||
@block = block
|
||||
@tests = []
|
||||
end
|
||||
|
||||
def evaluate(*args)
|
||||
instance_exec *args, &@block
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -32,7 +32,7 @@ module Producer
|
||||
end
|
||||
end
|
||||
|
||||
def test_macro(name, dsl: Condition::DSL, &block)
|
||||
def test_macro(name, dsl: Condition, &block)
|
||||
dsl.define_test(name, block)
|
||||
end
|
||||
|
||||
|
@ -1,116 +0,0 @@
|
||||
require 'spec_helper'
|
||||
|
||||
module Producer::Core
|
||||
class Condition
|
||||
describe DSL do
|
||||
let(:block) { proc { :some_condition_code } }
|
||||
let(:env) { double 'env' }
|
||||
subject(:dsl) { DSL.new(env, &block) }
|
||||
|
||||
%w[
|
||||
`
|
||||
sh
|
||||
file_contains
|
||||
file_eq
|
||||
dir?
|
||||
env?
|
||||
executable?
|
||||
file?
|
||||
].each do |test|
|
||||
it "has `#{test}' test defined" do
|
||||
expect(dsl).to respond_to test.to_sym
|
||||
end
|
||||
end
|
||||
|
||||
describe '.define_test' do
|
||||
let(:some_test) { Test }
|
||||
|
||||
before { described_class.define_test(:some_test, some_test) }
|
||||
|
||||
it 'defines a new test keyword' do
|
||||
expect(dsl).to respond_to :some_test
|
||||
end
|
||||
|
||||
it 'defines the negated test' do
|
||||
expect(dsl).to respond_to :no_some_test
|
||||
end
|
||||
|
||||
context 'when a test keyword is called' do
|
||||
it 'registers the test' do
|
||||
expect { dsl.some_test }.to change { dsl.tests.count }.by 1
|
||||
end
|
||||
|
||||
it 'registers the test with current env' do
|
||||
dsl.some_test
|
||||
expect(dsl.tests.last.env).to be env
|
||||
end
|
||||
|
||||
it 'registers the test with given arguments' do
|
||||
dsl.some_test :some, :args
|
||||
expect(dsl.tests.last.arguments).to eq [:some, :args]
|
||||
end
|
||||
|
||||
context 'when given test is callable' do
|
||||
let(:some_test) { proc {} }
|
||||
|
||||
before { dsl.some_test }
|
||||
|
||||
it 'registers a condition test' do
|
||||
expect(dsl.tests.last).to be_a Tests::ConditionTest
|
||||
end
|
||||
|
||||
it 'registers the test with given block' do
|
||||
expect(dsl.tests.last.condition_block).to be some_test
|
||||
end
|
||||
|
||||
it 'registers the test with given arguments' do
|
||||
dsl.some_test :some, :args
|
||||
expect(dsl.tests.last.condition_args).to eq [:some, :args]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a negated test keyword is called' do
|
||||
it 'registers a negated test' do
|
||||
dsl.no_some_test
|
||||
expect(dsl.tests.last).to be_negated
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#initialize' do
|
||||
it 'assigns the env' do
|
||||
expect(dsl.env).to be env
|
||||
end
|
||||
|
||||
it 'assigns the code' do
|
||||
expect(dsl.block).to be block
|
||||
end
|
||||
|
||||
it 'assigns no test' do
|
||||
expect(dsl.tests).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
describe '#evaluate' do
|
||||
it 'evaluates its code' do
|
||||
dsl = described_class.new(env) { throw :condition_code }
|
||||
expect { dsl.evaluate }.to throw_symbol :condition_code
|
||||
end
|
||||
|
||||
it 'returns the value returned by the assigned block' do
|
||||
expect(dsl.evaluate).to eq block.call
|
||||
end
|
||||
|
||||
context 'when arguments are given' do
|
||||
let(:block) { proc { |e| throw e } }
|
||||
|
||||
it 'passes arguments as block parameters' do
|
||||
expect { dsl.evaluate :some_argument }
|
||||
.to throw_symbol :some_argument
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -2,45 +2,128 @@ require 'spec_helper'
|
||||
|
||||
module Producer::Core
|
||||
describe Condition do
|
||||
let(:test_ok) { double 'test', pass?: true }
|
||||
let(:test_ko) { double 'test', pass?: false }
|
||||
let(:tests) { [test_ok, test_ko] }
|
||||
subject(:condition) { Condition.new(tests) }
|
||||
subject(:condition) { described_class.new }
|
||||
|
||||
describe '.evaluate' do
|
||||
let(:env) { double 'env' }
|
||||
let(:block) { proc { some_test; :some_return_value } }
|
||||
let(:some_test_class) { Class.new(Test) }
|
||||
subject(:condition) { described_class.evaluate(env, &block) }
|
||||
|
||||
before { Condition::DSL.define_test(:some_test, some_test_class) }
|
||||
|
||||
it 'returns an evaluated condition' do
|
||||
expect(condition.tests.first).to be_a Test
|
||||
expect(condition.return_value).to eq :some_return_value
|
||||
%w[
|
||||
`
|
||||
sh
|
||||
file_contains
|
||||
file_eq
|
||||
dir?
|
||||
env?
|
||||
executable?
|
||||
file?
|
||||
].each do |test|
|
||||
it "has `#{test}' test defined" do
|
||||
expect(condition).to respond_to test.to_sym
|
||||
end
|
||||
end
|
||||
|
||||
describe '#initialize' do
|
||||
it 'assigns the tests' do
|
||||
expect(condition.tests).to eq tests
|
||||
describe '.define_test' do
|
||||
let(:some_test) { Test }
|
||||
|
||||
before { described_class.define_test(:some_test, some_test) }
|
||||
|
||||
it 'defines a new test keyword' do
|
||||
expect(condition).to respond_to :some_test
|
||||
end
|
||||
|
||||
it 'assigns nil as a default return value' do
|
||||
expect(condition.return_value).to be nil
|
||||
it 'defines the negated test' do
|
||||
expect(condition).to respond_to :no_some_test
|
||||
end
|
||||
|
||||
context 'when a return value is given as argument' do
|
||||
let(:return_value) { :some_return_value }
|
||||
subject(:condition) { described_class.new(tests, return_value) }
|
||||
context 'when a test keyword is called' do
|
||||
it 'registers the test' do
|
||||
expect { condition.some_test }.to change { condition.tests.count }.by 1
|
||||
end
|
||||
|
||||
it 'assigns the return value' do
|
||||
expect(condition.return_value).to eq return_value
|
||||
it 'registers the test with assigned env' do
|
||||
env = double 'env'
|
||||
condition.instance_eval { @env = env }
|
||||
condition.some_test
|
||||
expect(condition.tests.last.env).to be env
|
||||
end
|
||||
|
||||
it 'registers the test with given arguments' do
|
||||
condition.some_test :foo, :bar
|
||||
expect(condition.tests.last.arguments).to eq %i[foo bar]
|
||||
end
|
||||
|
||||
context 'when given test is callable' do
|
||||
let(:some_test) { proc { } }
|
||||
|
||||
before { condition.some_test }
|
||||
|
||||
it 'registers a condition test' do
|
||||
expect(condition.tests.last).to be_a Tests::ConditionTest
|
||||
end
|
||||
|
||||
it 'registers the test with given block' do
|
||||
expect(condition.tests.last.condition_block).to be some_test
|
||||
end
|
||||
|
||||
it 'registers the test with given arguments' do
|
||||
condition.some_test :foo, :bar
|
||||
expect(condition.tests.last.condition_args).to eq %i[foo bar]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a negated test keyword is called' do
|
||||
it 'registers a negated test' do
|
||||
condition.no_some_test
|
||||
expect(condition.tests.last).to be_negated
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '.evaluate' do
|
||||
let(:env) { double 'env' }
|
||||
let(:code) { proc { some_test; :some_return_value } }
|
||||
let(:some_test) { Class.new(Test) }
|
||||
let(:arguments) { [] }
|
||||
subject(:condition) { described_class.evaluate(env, *arguments, &code) }
|
||||
|
||||
before { described_class.define_test(:some_test, some_test) }
|
||||
|
||||
it 'returns an evaluated condition' do
|
||||
expect(condition).to be_a Condition
|
||||
end
|
||||
|
||||
it 'evaluates the condition tests' do
|
||||
expect(condition.tests.first).to be_a Test
|
||||
end
|
||||
|
||||
it 'evaluates the condition return value' do
|
||||
expect(condition.return_value).to eq :some_return_value
|
||||
end
|
||||
|
||||
context 'when arguments are given' do
|
||||
let(:code) { proc { |a, b| throw a } }
|
||||
let(:arguments) { %i[foo bar] }
|
||||
|
||||
it 'passes arguments as block parameters' do
|
||||
expect { condition }
|
||||
.to throw_symbol :foo
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#initialize' do
|
||||
it 'assigns no tests' do
|
||||
expect(condition.tests).to be_empty
|
||||
end
|
||||
|
||||
it 'assigns the return value as nil' do
|
||||
expect(condition.return_value).to be nil
|
||||
end
|
||||
end
|
||||
|
||||
describe '#met?' do
|
||||
let(:test_ok) { instance_spy Test, pass?: true }
|
||||
let(:test_ko) { instance_spy Test, pass?: false }
|
||||
subject(:condition) { described_class.new(tests) }
|
||||
|
||||
context 'when all tests are successful' do
|
||||
let(:tests) { [test_ok, test_ok] }
|
||||
|
||||
@ -58,6 +141,7 @@ module Producer::Core
|
||||
end
|
||||
|
||||
context 'when there are no test' do
|
||||
let(:tests) { [] }
|
||||
subject(:condition) { described_class.new([], return_value) }
|
||||
|
||||
context 'and return value is truthy' do
|
||||
|
@ -74,7 +74,7 @@ module Producer::Core
|
||||
describe '#test_macro' do
|
||||
it 'defines the new test' do
|
||||
recipe.test_macro(:some_test) { }
|
||||
expect(Condition::DSL.new(env)).to respond_to :some_test
|
||||
expect(Condition.new).to respond_to :some_test
|
||||
end
|
||||
end
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user