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_replace_content'
|
||||||
require 'producer/core/actions/file_writer'
|
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/test'
|
||||||
require 'producer/core/tests/condition_test'
|
require 'producer/core/tests/condition_test'
|
||||||
require 'producer/core/tests/file_contains'
|
require 'producer/core/tests/file_contains'
|
||||||
@ -27,7 +27,6 @@ require 'producer/core/tests/shell_command_status'
|
|||||||
|
|
||||||
require 'producer/core/cli'
|
require 'producer/core/cli'
|
||||||
require 'producer/core/condition'
|
require 'producer/core/condition'
|
||||||
require 'producer/core/condition/dsl'
|
|
||||||
require 'producer/core/env'
|
require 'producer/core/env'
|
||||||
require 'producer/core/errors'
|
require 'producer/core/errors'
|
||||||
require 'producer/core/logger_formatter'
|
require 'producer/core/logger_formatter'
|
||||||
|
@ -2,16 +2,45 @@ module Producer
|
|||||||
module Core
|
module Core
|
||||||
class Condition
|
class Condition
|
||||||
class << self
|
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)
|
def evaluate(env, *args, &block)
|
||||||
dsl = DSL.new(env, &block)
|
new.tap do |o|
|
||||||
return_value = dsl.evaluate *args
|
o.instance_eval { @env = env }
|
||||||
Condition.new(dsl.tests, return_value)
|
return_value = o.instance_exec *args, &block
|
||||||
|
o.instance_eval { @return_value = return_value }
|
||||||
|
end
|
||||||
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 :tests, :return_value
|
attr_reader :tests, :return_value
|
||||||
|
|
||||||
def initialize(tests, return_value = nil)
|
def initialize(tests = [], return_value = nil)
|
||||||
@tests = tests
|
@tests = tests
|
||||||
@return_value = return_value
|
@return_value = return_value
|
||||||
end
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_macro(name, dsl: Condition::DSL, &block)
|
def test_macro(name, dsl: Condition, &block)
|
||||||
dsl.define_test(name, block)
|
dsl.define_test(name, block)
|
||||||
end
|
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
|
module Producer::Core
|
||||||
describe Condition do
|
describe Condition do
|
||||||
let(:test_ok) { double 'test', pass?: true }
|
subject(:condition) { described_class.new }
|
||||||
let(:test_ko) { double 'test', pass?: false }
|
|
||||||
let(:tests) { [test_ok, test_ko] }
|
|
||||||
subject(:condition) { Condition.new(tests) }
|
|
||||||
|
|
||||||
describe '.evaluate' do
|
%w[
|
||||||
let(:env) { double 'env' }
|
`
|
||||||
let(:block) { proc { some_test; :some_return_value } }
|
sh
|
||||||
let(:some_test_class) { Class.new(Test) }
|
file_contains
|
||||||
subject(:condition) { described_class.evaluate(env, &block) }
|
file_eq
|
||||||
|
dir?
|
||||||
before { Condition::DSL.define_test(:some_test, some_test_class) }
|
env?
|
||||||
|
executable?
|
||||||
it 'returns an evaluated condition' do
|
file?
|
||||||
expect(condition.tests.first).to be_a Test
|
].each do |test|
|
||||||
expect(condition.return_value).to eq :some_return_value
|
it "has `#{test}' test defined" do
|
||||||
|
expect(condition).to respond_to test.to_sym
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#initialize' do
|
describe '.define_test' do
|
||||||
it 'assigns the tests' do
|
let(:some_test) { Test }
|
||||||
expect(condition.tests).to eq tests
|
|
||||||
|
before { described_class.define_test(:some_test, some_test) }
|
||||||
|
|
||||||
|
it 'defines a new test keyword' do
|
||||||
|
expect(condition).to respond_to :some_test
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'assigns nil as a default return value' do
|
it 'defines the negated test' do
|
||||||
expect(condition.return_value).to be nil
|
expect(condition).to respond_to :no_some_test
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when a return value is given as argument' do
|
context 'when a test keyword is called' do
|
||||||
let(:return_value) { :some_return_value }
|
it 'registers the test' do
|
||||||
subject(:condition) { described_class.new(tests, return_value) }
|
expect { condition.some_test }.to change { condition.tests.count }.by 1
|
||||||
|
end
|
||||||
|
|
||||||
it 'assigns the return value' do
|
it 'registers the test with assigned env' do
|
||||||
expect(condition.return_value).to eq return_value
|
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
|
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
|
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
|
context 'when all tests are successful' do
|
||||||
let(:tests) { [test_ok, test_ok] }
|
let(:tests) { [test_ok, test_ok] }
|
||||||
|
|
||||||
@ -58,6 +141,7 @@ module Producer::Core
|
|||||||
end
|
end
|
||||||
|
|
||||||
context 'when there are no test' do
|
context 'when there are no test' do
|
||||||
|
let(:tests) { [] }
|
||||||
subject(:condition) { described_class.new([], return_value) }
|
subject(:condition) { described_class.new([], return_value) }
|
||||||
|
|
||||||
context 'and return value is truthy' do
|
context 'and return value is truthy' do
|
||||||
|
@ -74,7 +74,7 @@ module Producer::Core
|
|||||||
describe '#test_macro' do
|
describe '#test_macro' do
|
||||||
it 'defines the new test' do
|
it 'defines the new test' do
|
||||||
recipe.test_macro(:some_test) { }
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user