diff --git a/lib/producer/core/recipe/dsl.rb b/lib/producer/core/recipe/dsl.rb index a088209..8076aad 100644 --- a/lib/producer/core/recipe/dsl.rb +++ b/lib/producer/core/recipe/dsl.rb @@ -22,7 +22,6 @@ module Producer else instance_eval &@block end - @tasks.each { |e| e.evaluate env } self end @@ -41,7 +40,7 @@ module Producer end def task(name, &block) - @tasks << Task.new(name, &block) + @tasks << Task.evaluate(name, env, &block) end end end diff --git a/lib/producer/core/task.rb b/lib/producer/core/task.rb index 5bb8cd2..f5bd83a 100644 --- a/lib/producer/core/task.rb +++ b/lib/producer/core/task.rb @@ -3,16 +3,13 @@ module Producer class Task attr_reader :name, :actions - def initialize(name, &block) - @name = name - @block = block - @actions = [] + def self.evaluate(name, env, &block) + DSL::evaluate(name, env, &block) end - def evaluate(env) - dsl = DSL.new(&@block) - dsl.evaluate(env) - @actions = dsl.actions + def initialize(name, actions = []) + @name = name + @actions = actions end end end diff --git a/lib/producer/core/task/dsl.rb b/lib/producer/core/task/dsl.rb index fdcff71..1103604 100644 --- a/lib/producer/core/task/dsl.rb +++ b/lib/producer/core/task/dsl.rb @@ -3,6 +3,12 @@ module Producer class Task class DSL class << self + def evaluate(name, env, &block) + dsl = new(&block) + dsl.evaluate(env) + Task.new(name, dsl.actions) + end + def define_action(keyword, klass) define_method(keyword) do |*args| @actions << klass.new(@env, *args) diff --git a/spec/producer/core/recipe/dsl_spec.rb b/spec/producer/core/recipe/dsl_spec.rb index be3b7ce..0489724 100644 --- a/spec/producer/core/recipe/dsl_spec.rb +++ b/spec/producer/core/recipe/dsl_spec.rb @@ -73,14 +73,6 @@ module Producer::Core expect { dsl.evaluate(env) }.to throw_symbol :recipe_code end - it 'evaluates the registered tasks' do - task = double('task') - allow(Task).to receive(:new) { task } - dsl = Recipe::DSL.new { task(:some_task) } - expect(task).to receive(:evaluate).with(env) - dsl.evaluate(env) - end - it 'returns itself' do expect(dsl.evaluate(env)).to eq dsl end @@ -118,16 +110,20 @@ module Producer::Core end describe '#task' do - let(:code) { proc { task(:first) { :some_value }; task(:last) { } } } + let(:code) { proc { task(:some_task) { :some_value } } } - it 'register a task with its code' do - expect(dsl.tasks.first.instance_eval { @block.call }) - .to eq :some_value + it 'builds a new evaluated task' do + expect(Task) + .to receive(:evaluate).with(:some_task, env) do |&block| + expect(block.call).to eq :some_value + end + dsl end - it 'registers tasks in declaration order' do - expect(dsl.tasks[0].name).to eq :first - expect(dsl.tasks[1].name).to eq :last + it 'registers the new task' do + task = double('task').as_null_object + allow(Task).to receive(:new) { task } + expect(dsl.tasks).to include(task) end end end diff --git a/spec/producer/core/task/dsl_spec.rb b/spec/producer/core/task/dsl_spec.rb index 6d5575e..38b508d 100644 --- a/spec/producer/core/task/dsl_spec.rb +++ b/spec/producer/core/task/dsl_spec.rb @@ -12,6 +12,36 @@ module Producer::Core end end + describe '.evaluate' do + let(:name) { :some_task } + + it 'builds a new DSL sandbox with given code' do + expect(Task::DSL).to receive(:new).once.with(&block).and_call_original + Task::DSL.evaluate(name, env, &block) + end + + it 'evaluates the DSL sandbox code with given environment' do + dsl = double('dsl').as_null_object + allow(Task::DSL).to receive(:new) { dsl } + expect(dsl).to receive(:evaluate).with(env) + Task::DSL.evaluate(name, env, &block) + end + + it 'builds a task with its name and registered actions' do + dsl = double('dsl').as_null_object + allow(Task::DSL).to receive(:new) { dsl } + allow(dsl).to receive(:actions) { [:some_action]} + expect(Task).to receive(:new).with(:some_task, [:some_action]) + Task::DSL.evaluate(name, env, &block) + end + + it 'returns the task' do + task = double('task') + allow(Task).to receive(:new) { task } + expect(Task::DSL.evaluate(name, env, &block)).to be task + end + end + describe '.define_action' do it 'defines a new action keyword' do Task::DSL.define_action(:some_action, Object) diff --git a/spec/producer/core/task_spec.rb b/spec/producer/core/task_spec.rb index eb3112f..303aacf 100644 --- a/spec/producer/core/task_spec.rb +++ b/spec/producer/core/task_spec.rb @@ -3,20 +3,41 @@ require 'spec_helper' module Producer::Core describe Task do let(:name) { :some_task } - let(:block) { proc { } } - subject(:task) { Task.new(name, &block) } + let(:action) { double('action') } + subject(:task) { Task.new(name, [action]) } + + describe '.evaluate' do + let(:env) { double('env') } + let(:block) { proc { } } + + it 'delegates to DSL.evaluate' do + expect(Task::DSL) + .to receive(:evaluate).with(name, env, &block) + Task.evaluate(name, env, &block) + end + + it 'returns the evaluated task' do + task = double('task') + allow(Task::DSL).to receive(:evaluate) { task } + expect(Task.evaluate(name, env, &block)).to be task + end + end describe '#initialize' do it 'assigns the name' do expect(task.instance_eval { @name }).to eq name end - it 'assigns the block' do - expect(task.instance_eval { @block }).to be block + it 'assigns the actions' do + expect(task.instance_eval { @actions }).to eq [action] end - it 'has no action' do - expect(task.actions).to be_empty + context 'when only the name is given as argument' do + subject(:task) { Task.new(name) } + + it 'has assigns no action' do + expect(task.actions).to be_empty + end end end @@ -26,27 +47,9 @@ module Producer::Core end end - describe '#evaluate' do - let(:env) { double('env') } - - it 'builds a task DSL sandbox' do - expect(Task::DSL).to receive(:new).with(&block).and_call_original - task.evaluate(env) - end - - it 'evaluates the task DSL sandbox' do - 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 'assigns the evaluated actions' do - dsl = double('dsl').as_null_object - allow(Task::DSL).to receive(:new) { dsl } - allow(dsl).to receive(:actions) { [:some_action] } - task.evaluate(env) - expect(task.actions).to eq [:some_action] + describe '#actions' do + it 'returns the assigned actions' do + expect(task.actions).to eq [action] end end end