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/env'
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
def evaluate(env)
DSL.new(&@block).evaluate(env)
dsl = DSL.new(&@block)
dsl.evaluate(env)
dsl.actions.map(&:apply)
end
end
end

View File

@ -2,11 +2,23 @@ module Producer
module Core
class Task
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)
@block = block
@block = block
@actions = []
end
def evaluate(env)
@env = env
instance_eval &@block
rescue ConditionNotMetError
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
describe Task::DSL do
let(:block) { proc { } }
let(:env) { double('env') }
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
let(:block) { proc { throw :task_code } }
@ -13,6 +27,24 @@ module Producer::Core
.to throw_symbol :task_code
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
it 'raises a TaskEvaluationError on NameError' do
dsl = Task::DSL.new { invalid_action }

View File

@ -21,11 +21,20 @@ module Producer::Core
end
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 }
expect(dsl).to receive(:evaluate).with(env)
task.evaluate(env)
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