Implement basic task actions API:

* Add Action base class;
* Implement Task::DSL.define_action(keyword, klass);
* Add Task::DSL#actions accessor;
* Apply task DSL actions when Task instances are evaluated.
This commit is contained in:
Thibault Jouan 2013-08-03 14:45:14 +00:00
parent 8e455fc4d5
commit e6c14f1903
7 changed files with 92 additions and 3 deletions

View File

@ -1,3 +1,4 @@
require 'producer/core/action'
require 'producer/core/cli' require 'producer/core/cli'
require 'producer/core/env' require 'producer/core/env'
require 'producer/core/errors' require 'producer/core/errors'

View File

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

View File

@ -9,7 +9,9 @@ module Producer
end end
def evaluate(env) def evaluate(env)
DSL.new(&@block).evaluate(env) dsl = DSL.new(&@block)
dsl.evaluate(env)
dsl.actions.map(&:apply)
end end
end end
end end

View File

@ -2,11 +2,23 @@ module Producer
module Core module Core
class Task class Task
class DSL class DSL
class << self
def define_action(keyword, klass)
define_method(keyword) do |*args|
@actions << klass.new(@env, *args)
end
end
end
attr_accessor :actions
def initialize(&block) def initialize(&block)
@block = block @block = block
@actions = []
end end
def evaluate(env) def evaluate(env)
@env = env
instance_eval &@block instance_eval &@block
rescue ConditionNotMetError rescue ConditionNotMetError
rescue NameError => e rescue NameError => e

View File

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

View File

@ -2,9 +2,23 @@ require 'spec_helper'
module Producer::Core module Producer::Core
describe Task::DSL do describe Task::DSL do
let(:block) { proc { } }
let(:env) { double('env') } let(:env) { double('env') }
subject(:dsl) { Task::DSL.new &block } subject(:dsl) { Task::DSL.new &block }
describe '.define_action' do
it 'defines a new action keyword' do
Task::DSL.define_action(:some_action, Object)
expect(dsl).to respond_to :some_action
end
end
describe '#initialize' do
it 'has no action' do
expect(dsl.actions).to eq []
end
end
describe '#evaluate' do describe '#evaluate' do
let(:block) { proc { throw :task_code } } let(:block) { proc { throw :task_code } }
@ -13,6 +27,24 @@ module Producer::Core
.to throw_symbol :task_code .to throw_symbol :task_code
end end
context 'when a defined keyword action is called' do
let(:some_action_class) { Class.new(Action) }
let(:block) { proc { some_action } }
before do
Task::DSL.define_action(:some_action, some_action_class)
dsl.evaluate(env)
end
it 'registers the action' do
expect(dsl.actions.first).to be_an Action
end
it 'provides the env to the registered action' do
expect(dsl.actions.first.env).to eq env
end
end
context 'when given block is invalid' do context 'when given block is invalid' do
it 'raises a TaskEvaluationError on NameError' do it 'raises a TaskEvaluationError on NameError' do
dsl = Task::DSL.new { invalid_action } dsl = Task::DSL.new { invalid_action }

View File

@ -21,11 +21,20 @@ module Producer::Core
end end
it 'evaluates the task DSL sandbox' do it 'evaluates the task DSL sandbox' do
dsl = double('task dsl') dsl = double('task DSL').as_null_object
allow(Task::DSL).to receive(:new) { dsl } allow(Task::DSL).to receive(:new) { dsl }
expect(dsl).to receive(:evaluate).with(env) expect(dsl).to receive(:evaluate).with(env)
task.evaluate(env) task.evaluate(env)
end end
it 'applies DSL sandbox actions' do
dsl = double('task DSL').as_null_object
allow(Task::DSL).to receive(:new) { dsl }
action = double('action')
allow(dsl).to receive(:actions) { [action] }
expect(action).to receive(:apply)
task.evaluate(env)
end
end end
end end
end end