From 82879b56b41e539f1cfd2612665879c5b25ade81 Mon Sep 17 00:00:00 2001 From: Thibault Jouan Date: Fri, 10 Oct 2014 15:48:00 +0000 Subject: [PATCH] Extract Task#template code in Template class --- features/task_template.feature | 30 +++++++++++++++-------- lib/producer/core.rb | 1 + lib/producer/core/task.rb | 17 +------------- lib/producer/core/template.rb | 34 +++++++++++++++++++++++++++ spec/fixtures/templates/basic.erb | 1 + spec/fixtures/templates/variables.erb | 1 + spec/producer/core/template_spec.rb | 33 ++++++++++++++++++++++++++ 7 files changed, 91 insertions(+), 26 deletions(-) create mode 100644 lib/producer/core/template.rb create mode 100644 spec/fixtures/templates/basic.erb create mode 100644 spec/fixtures/templates/variables.erb create mode 100644 spec/producer/core/template_spec.rb diff --git a/features/task_template.feature b/features/task_template.feature index b2a4725..cad3619 100644 --- a/features/task_template.feature +++ b/features/task_template.feature @@ -1,17 +1,11 @@ Feature: `template' task keyword - Background: - Given a file named "basic.erb" with: + Scenario: renders an ERB template file + Given a file named "templates/basic.erb" with: """ basic template """ - Given a file named "variables.erb" with: - """ - <%= @foo %> - """ - - Scenario: renders an ERB template file - Given a recipe with: + And a recipe with: """ task(:echo_template) { echo template 'basic' } """ @@ -19,9 +13,25 @@ Feature: `template' task keyword Then the output must contain "basic template" Scenario: renders ERB with given attributes as member data - Given a recipe with: + Given a file named "templates/variables.erb" with: + """ + <%= @foo %> + """ + And a recipe with: """ task(:echo_template) { echo template('variables', foo: 'bar') } """ When I execute the recipe Then the output must contain "bar" + + Scenario: renders without `templates' search path + Given a file named "templates/basic.erb" with: + """ + basic template + """ + And a recipe with: + """ + task(:echo_template) { echo template './templates/basic' } + """ + When I execute the recipe + Then the output must contain "basic template" diff --git a/lib/producer/core.rb b/lib/producer/core.rb index 5259b41..6f061dc 100644 --- a/lib/producer/core.rb +++ b/lib/producer/core.rb @@ -41,5 +41,6 @@ require 'producer/core/remote' require 'producer/core/remote/environment' require 'producer/core/remote/fs' require 'producer/core/task' +require 'producer/core/template' require 'producer/core/version' require 'producer/core/worker' diff --git a/lib/producer/core/task.rb b/lib/producer/core/task.rb index 3d3da75..df31246 100644 --- a/lib/producer/core/task.rb +++ b/lib/producer/core/task.rb @@ -59,22 +59,7 @@ module Producer end def template(path, variables = {}) - path = "#{path}.erb" - tpl = ERB.new(File.read(path), nil, '-') - tpl.filename = path - tpl.result build_erb_binding variables - end - - - private - - def build_erb_binding(variables) - Object.new.instance_eval do |o| - variables.each do |k, v| - o.instance_variable_set "@#{k}", v - end - binding - end + Template.new(path).render variables end end end diff --git a/lib/producer/core/template.rb b/lib/producer/core/template.rb new file mode 100644 index 0000000..f6f2941 --- /dev/null +++ b/lib/producer/core/template.rb @@ -0,0 +1,34 @@ +module Producer + module Core + class Template + SEARCH_PATH = 'templates'.freeze + + def initialize(path, search_path: SEARCH_PATH) + @path = Pathname.new("#{path}.erb") + @search_path = Pathname.new(search_path) + end + + def render(variables = {}) + tpl = ERB.new(File.read(resolve_path), nil, '-') + tpl.filename = resolve_path.to_s + tpl.result build_erb_binding variables + end + + + private + + def resolve_path + if @path.to_s =~ /\A\.\// then @path else @search_path + @path end + end + + def build_erb_binding(variables) + Object.new.instance_eval do |o| + variables.each do |k, v| + o.instance_variable_set "@#{k}", v + end + binding + end + end + end + end +end diff --git a/spec/fixtures/templates/basic.erb b/spec/fixtures/templates/basic.erb new file mode 100644 index 0000000..4657c1f --- /dev/null +++ b/spec/fixtures/templates/basic.erb @@ -0,0 +1 @@ +basic template diff --git a/spec/fixtures/templates/variables.erb b/spec/fixtures/templates/variables.erb new file mode 100644 index 0000000..5457532 --- /dev/null +++ b/spec/fixtures/templates/variables.erb @@ -0,0 +1 @@ +<%= @foo %> diff --git a/spec/producer/core/template_spec.rb b/spec/producer/core/template_spec.rb new file mode 100644 index 0000000..59348d3 --- /dev/null +++ b/spec/producer/core/template_spec.rb @@ -0,0 +1,33 @@ +require 'spec_helper' + +module Producer::Core + describe Template do + include FixturesHelpers + + let(:path) { 'basic' } + let(:search_path) { fixture_path_for 'templates' } + subject(:template) { described_class.new path, search_path: search_path } + + describe '#render' do + it 'renders ERB templates' do + expect(template.render).to eq "basic template\n" + end + + context 'when variables are given' do + let(:path) { 'variables' } + + it 'declares given variables in ERB render binding' do + expect(template.render foo: 'bar').to eq "bar\n" + end + end + + context 'when relative path is requested' do + let(:path) { fixture_path_for('templates/basic').insert 0, './' } + + it 'does not enforce `template\' search path' do + expect(template.render).to eq "basic template\n" + end + end + end + end +end