Implement recipe evaluation feature
This commit is contained in:
parent
f0d90c96e9
commit
0921be9ab0
10
features/recipe.feature
Normal file
10
features/recipe.feature
Normal file
@ -0,0 +1,10 @@
|
||||
Feature: recipe evaluation
|
||||
|
||||
Scenario: evaluates ruby code in a recipe
|
||||
Given a recipe with:
|
||||
"""
|
||||
puts 'hello from recipe'
|
||||
"""
|
||||
When I execute the recipe
|
||||
Then the exit status must be 0
|
||||
And the output must contain "hello from recipe"
|
7
features/steps/recipe_steps.rb
Normal file
7
features/steps/recipe_steps.rb
Normal file
@ -0,0 +1,7 @@
|
||||
Given(/^a recipe with:$/) do |recipe_body|
|
||||
write_file 'recipe.rb', recipe_body
|
||||
end
|
||||
|
||||
When(/^I execute the recipe$/) do
|
||||
run_simple('producer localhost recipe.rb', false)
|
||||
end
|
@ -2,6 +2,7 @@ require 'producer/core/version'
|
||||
|
||||
module Producer
|
||||
module Core
|
||||
autoload :CLI, 'producer/core/cli'
|
||||
autoload :CLI, 'producer/core/cli'
|
||||
autoload :Recipe, 'producer/core/recipe'
|
||||
end
|
||||
end
|
||||
|
@ -12,6 +12,8 @@ module Producer
|
||||
|
||||
def run!
|
||||
print_usage_and_exit(64) unless @arguments.length == 2
|
||||
|
||||
Recipe.from_file(@arguments[1]).evaluate
|
||||
end
|
||||
|
||||
|
||||
|
19
lib/producer/core/recipe.rb
Normal file
19
lib/producer/core/recipe.rb
Normal file
@ -0,0 +1,19 @@
|
||||
module Producer
|
||||
module Core
|
||||
class Recipe
|
||||
attr_reader :code
|
||||
|
||||
def self.from_file(filepath)
|
||||
new(File.read(filepath))
|
||||
end
|
||||
|
||||
def initialize(code)
|
||||
@code = code
|
||||
end
|
||||
|
||||
def evaluate
|
||||
Object.new.instance_eval @code
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
1
spec/fixtures/recipes/empty.rb
vendored
Normal file
1
spec/fixtures/recipes/empty.rb
vendored
Normal file
@ -0,0 +1 @@
|
||||
# can contain tasks written in ruby language.
|
@ -2,7 +2,9 @@ require 'spec_helper'
|
||||
|
||||
module Producer::Core
|
||||
describe CLI do
|
||||
let(:arguments) { %w{host recipe.rb} }
|
||||
include FixturesHelpers
|
||||
|
||||
let(:arguments) { ['host', fixture_path_for('recipes/empty.rb')] }
|
||||
subject(:cli) { CLI.new(arguments) }
|
||||
|
||||
describe '#initialize' do
|
||||
@ -12,6 +14,18 @@ module Producer::Core
|
||||
end
|
||||
|
||||
describe '#run!' do
|
||||
it 'builds a recipe' do
|
||||
expect(Recipe).to receive(:from_file).with(arguments[1]).and_call_original
|
||||
cli.run!
|
||||
end
|
||||
|
||||
it 'evaluates the recipe' do
|
||||
recipe = double('recipe')
|
||||
allow(Recipe).to receive(:from_file).and_return(recipe)
|
||||
expect(recipe).to receive(:evaluate)
|
||||
cli.run!
|
||||
end
|
||||
|
||||
context 'missing argument' do
|
||||
let(:arguments) { %w{host} }
|
||||
let(:stdout) { StringIO.new }
|
||||
|
39
spec/producer/core/recipe_spec.rb
Normal file
39
spec/producer/core/recipe_spec.rb
Normal file
@ -0,0 +1,39 @@
|
||||
require 'spec_helper'
|
||||
|
||||
module Producer::Core
|
||||
describe Recipe do
|
||||
include FixturesHelpers
|
||||
|
||||
let(:code) { 'some ruby code' }
|
||||
subject(:recipe) { Recipe.new(code) }
|
||||
|
||||
describe '.from_file' do
|
||||
it 'builds a recipe whose code is read from given file path' do
|
||||
filepath = fixture_path_for 'recipes/empty.rb'
|
||||
recipe = Recipe.from_file(filepath)
|
||||
expect(recipe.code).to eq File.read(filepath)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#initialize' do
|
||||
it 'builds a recipe' do
|
||||
expect(recipe).to be_a Recipe
|
||||
end
|
||||
end
|
||||
|
||||
describe '#code' do
|
||||
it 'returns the assigned code' do
|
||||
expect(recipe.code).to eq code
|
||||
end
|
||||
end
|
||||
|
||||
describe '#evaluate' do
|
||||
let(:message) { 'error from recipe' }
|
||||
let(:code) { "raise '#{message}'" }
|
||||
|
||||
it 'evaluates its code' do
|
||||
expect { recipe.evaluate }.to raise_error(RuntimeError, 'error from recipe')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
x
Reference in New Issue
Block a user