Build conditions with DSL evaluated tests:

In Condition:

  * Modify constructor to accepts tests and a default return value;
  * Implement #met?;
  * Modify #! so that it return the negated value returned by #met?.

  In Condition::DSL:

  * Modify .evaluate to build the condition with tests and the value
    returned by a the evaluated condition block.

  Add a basic Test base class, with env and arguments as attributes.

  Add some spec helpers to build some easily testable kind of Test
instances (as test doubles).
This commit is contained in:
Thibault Jouan 2013-08-17 22:06:07 +00:00
parent 00a11e159f
commit ed99c191e0
10 changed files with 137 additions and 15 deletions

View File

@ -1,6 +1,11 @@
# task actions
require 'producer/core/action'
require 'producer/core/actions/echo'
require 'producer/core/actions/shell_command'
# condition tests (need to be defined before the condition DSL)
require 'producer/core/test'
require 'producer/core/cli'
require 'producer/core/condition'
require 'producer/core/condition/dsl'

View File

@ -7,12 +7,19 @@ module Producer
end
end
def initialize(expression)
@expression = expression
def initialize(tests, return_value = nil)
@tests = tests
@return_value = return_value
end
def met?
return !!@return_value if @tests.empty?
@tests.each { |t| return false unless t.success? }
true
end
def !
!@expression
!met?
end
end
end

View File

@ -5,7 +5,8 @@ module Producer
class << self
def evaluate(env, &block)
dsl = new(env, &block)
Condition.new(dsl.evaluate)
return_value = dsl.evaluate
Condition.new(dsl.tests, return_value)
end
def define_test(keyword, klass)

12
lib/producer/core/test.rb Normal file
View File

@ -0,0 +1,12 @@
module Producer
module Core
class Test
attr_reader :env, :arguments
def initialize(env, *arguments)
@env = env
@arguments = arguments
end
end
end
end

View File

@ -14,15 +14,15 @@ module Producer::Core
end
it 'evaluates the DSL sandbox code' do
dsl = double('dsl')
dsl = double('dsl').as_null_object
allow(Condition::DSL).to receive(:new) { dsl }
expect(dsl).to receive(:evaluate)
Condition::DSL.evaluate(env, &block)
end
it 'builds a condition with value returned from DSL evaluation' do
it 'builds a condition with its test and block return value' do
expect(Condition)
.to receive(:new).with(dsl.evaluate)
.to receive(:new).with(dsl.tests, :some_condition_code)
Condition::DSL.evaluate(env, &block)
end

View File

@ -2,8 +2,10 @@ require 'spec_helper'
module Producer::Core
describe Condition do
let(:expression) { double('expression') }
let(:condition) { Condition.new(expression) }
include TestsHelpers
let(:tests) { [test_ok, test_ko] }
subject(:condition) { Condition.new(tests) }
describe '.evaluate' do
let(:env) { double('env') }
@ -25,14 +27,69 @@ module Producer::Core
end
describe '#initialize' do
it 'assigns the expression' do
expect(condition.instance_eval { @expression }).to be expression
it 'assigns the tests' do
expect(condition.instance_eval { @tests }).to eq tests
end
it 'assigns nil as a default return value' do
expect(condition.instance_eval { @return_value }).to be nil
end
context 'when a return value is given as argument' do
let(:return_value) { :some_return_value }
subject(:condition) { Condition.new(tests, return_value) }
it 'assigns the return value' do
expect(condition.instance_eval { @return_value }).to eq return_value
end
end
end
describe '#met?' do
context 'when all tests are successful' do
let(:tests) { [test_ok, test_ok] }
it 'returns true' do
expect(condition.met?).to be true
end
end
context 'when one test is unsuccessful' do
let(:tests) { [test_ok, test_ko] }
it 'returns false' do
expect(condition.met?).to be false
end
end
context 'when there are no test' do
subject(:condition) { Condition.new([], return_value) }
context 'and return value is truthy' do
let(:return_value) { :some_truthy_value }
it 'returns true' do
expect(condition.met?).to be true
end
end
context 'and return value is falsy' do
let(:return_value) { nil }
it 'returns false' do
expect(condition.met?).to be false
end
end
end
end
describe '#!' do
it 'returns the negated expression' do
expect(condition.!).to be !expression
%w[true false].each do |b|
context "when #met? return #{b}" do
it 'returns the negated #met?' do
expect(condition.!).to be !condition.met?
end
end
end
end
end

View File

@ -72,7 +72,7 @@ module Producer::Core
describe '#condition_met?' do
context 'when condition is truthy' do
let(:condition) { Condition.new(true) }
let(:condition) { Condition.new([], true) }
it 'returns true' do
expect(task.condition_met?).to be true
@ -80,7 +80,7 @@ module Producer::Core
end
context 'when condition is falsy' do
let(:condition) { Condition.new(false) }
let(:condition) { Condition.new([], false) }
it 'returns false' do
expect(task.condition_met?).to be false

View File

@ -0,0 +1,30 @@
require 'spec_helper'
module Producer::Core
describe Test do
let(:env) { double 'env' }
let(:arguments) { [:some, :arguments] }
subject(:action) { Test.new(env, *arguments) }
describe '#initialize' do
it 'assigns the env' do
expect(action.instance_eval { @env }).to be env
end
it 'assigns the arguments' do
expect(action.instance_eval { @arguments }).to eq arguments
end
end
describe '#env' do
it 'returns the assigned env' do
expect(action.env).to be env
end
end
describe '#arguments' do
it 'returns the assigned arguments' do
expect(action.arguments).to eq arguments
end
end
end
end

View File

@ -3,6 +3,7 @@ require 'producer/core'
require 'support/exit_helpers'
require 'support/fixtures_helpers'
require 'support/net_ssh_story_helpers'
require 'support/tests_helpers'
RSpec.configure do |c|

View File

@ -0,0 +1,9 @@
module TestsHelpers
def test_ok
double('test', success?: true)
end
def test_ko
double('test', success?: false)
end
end