deas-erubis 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.log
3
+ *.rbc
4
+ .rbx/
5
+ .bundle
6
+ .config
7
+ .yardoc
8
+ Gemfile.lock
9
+ InstalledFiles
10
+ _yardoc
11
+ coverage
12
+ doc/
13
+ lib/bundler/man
14
+ pkg
15
+ rdoc
16
+ spec/reports
17
+ test/tmp
18
+ test/version_tmp
19
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem 'rake'
6
+ gem 'pry', "~> 0.9.0"
7
+
8
+ platform :rbx do
9
+ gem 'rubysl'
10
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014-Present Kelly Redding and Collin Redding
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Deas::Erubis
2
+
3
+ [Deas](https://github.com/redding/deas) template engine for rendering [Erubis](http://www.kuwata-lab.com/erubis/) templates
4
+
5
+ ## Usage
6
+
7
+ TODO: Write code samples and usage instructions here
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ gem 'deas-erubis'
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install deas-erubis
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "deas-erubis/version"
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "deas-erubis"
8
+ gem.version = Deas::Erubis::VERSION
9
+ gem.authors = ["Kelly Redding", "Collin Redding"]
10
+ gem.email = ["kelly@kellyredding.com", "collin.redding@me.com"]
11
+ gem.description = %q{Deas template engine for rendering erb templates using Erubis}
12
+ gem.summary = %q{Deas template engine for rendering erb templates using Erubis}
13
+ gem.homepage = "http://github.com/redding/deas-erubis"
14
+ gem.license = 'MIT'
15
+
16
+ gem.files = `git ls-files`.split($/)
17
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
+ gem.require_paths = ["lib"]
20
+
21
+ gem.add_development_dependency("assert", ["~> 2.12"])
22
+
23
+ gem.add_dependency("deas", ["~> 0.29"])
24
+ gem.add_dependency("erubis")
25
+
26
+ end
@@ -0,0 +1,134 @@
1
+ require 'pathname'
2
+ require 'erubis'
3
+ require 'deas-erubis/template_helpers'
4
+
5
+ module Deas; end
6
+ module Deas::Erubis
7
+
8
+ class Source
9
+
10
+ EXT = '.erb'.freeze
11
+ CACHE_EXT = '.cache'.freeze
12
+ BUFVAR_NAME = '@_erb_buf'.freeze
13
+ DEFAULT_ERUBY = ::Erubis::Eruby
14
+
15
+ attr_reader :root, :cache_root, :eruby_class, :context_class
16
+
17
+ def initialize(root, opts)
18
+ @root = Pathname.new(root.to_s)
19
+ @eruby_class = opts[:eruby] || DEFAULT_ERUBY
20
+
21
+ should_cache = !!opts[:cache]
22
+ @cache_root = opts[:cache] == true ? @root : Pathname.new(opts[:cache].to_s)
23
+ @cache_root.mkpath if should_cache && !@cache_root.exist?
24
+
25
+ if should_cache
26
+ # use `load_file` to lookup and cache templates (faster renders)
27
+ if @cache_root == @root
28
+ # use the `load_file` default and don't bother with looking up, setting,
29
+ # and making sure the cache file path exists - by default `load_file`
30
+ # caches alongside the source with the `CACHE_EXT` appended.
31
+ add_meta_eruby_method do |file_name|
32
+ @eruby_class.load_file(source_file_path(file_name), {
33
+ :bufvar => BUFVAR_NAME
34
+ })
35
+ end
36
+ else
37
+ # lookup and ensure the custom cache location exists (more expensive)
38
+ add_meta_eruby_method do |file_name|
39
+ @eruby_class.load_file(source_file_path(file_name), {
40
+ :bufvar => BUFVAR_NAME,
41
+ :cachename => cache_file_path(file_name)
42
+ })
43
+ end
44
+ end
45
+ else
46
+ # don't cache template files (slower renders, but no cache files created)
47
+ add_meta_eruby_method do |file_name|
48
+ filename = source_file_path(file_name).to_s
49
+ template = File.send(File.respond_to?(:binread) ? :binread : :read, filename)
50
+ @eruby_class.new(template, {
51
+ :bufvar => BUFVAR_NAME,
52
+ :filename => filename
53
+ })
54
+ end
55
+ end
56
+
57
+ @deas_source = opts[:deas_source]
58
+ @context_class = build_context_class(opts)
59
+ end
60
+
61
+ def eruby(file_name)
62
+ # should be overridden by a metaclass equivalent on init
63
+ # the implementation changes whether you are caching templates or not
64
+ # and the goal here is to not add a bunch of conditional overhead as this
65
+ # will be called on every render
66
+ raise NotImplementedError
67
+ end
68
+
69
+ def render(file_name, locals, &content)
70
+ eruby(file_name).evaluate(@context_class.new(@deas_source, locals), &content)
71
+ end
72
+
73
+ def compile(file_name, content)
74
+ @eruby_class.new(content, {
75
+ :bufvar => BUFVAR_NAME,
76
+ :filename => file_name
77
+ }).evaluate(@context_class.new(@deas_source, {}))
78
+ end
79
+
80
+ def inspect
81
+ "#<#{self.class}:#{'0x0%x' % (object_id << 1)}"\
82
+ " @root=#{@root.inspect}"\
83
+ " @eruby=#{@eruby_class.inspect}>"
84
+ end
85
+
86
+ private
87
+
88
+ def source_file_path(file_name)
89
+ self.root.join("#{file_name}#{EXT}").to_s
90
+ end
91
+
92
+ def cache_file_path(file_name)
93
+ self.cache_root.join("#{file_name}#{EXT}#{CACHE_EXT}").tap do |path|
94
+ path.dirname.mkpath if !path.dirname.exist?
95
+ end.to_s
96
+ end
97
+
98
+ def add_meta_eruby_method(&method)
99
+ metaclass = class << self; self; end
100
+ metaclass.class_eval do
101
+ define_method(:eruby, &method)
102
+ end
103
+ end
104
+
105
+ def build_context_class(opts)
106
+ Class.new do
107
+ include ::Deas::Erubis::TemplateHelpers
108
+ # TODO: mixin context helpers? `opts[:template_helpers]`
109
+ (opts[:default_locals] || {}).each{ |k, v| define_method(k){ v } }
110
+
111
+ def initialize(deas_source, locals)
112
+ @deas_source = deas_source
113
+
114
+ metaclass = class << self; self; end
115
+ metaclass.class_eval do
116
+ locals.each do |key, value|
117
+ define_method(key){ value }
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
123
+
124
+ end
125
+
126
+ class DefaultSource < Source
127
+
128
+ def initialize
129
+ super('/', {})
130
+ end
131
+
132
+ end
133
+
134
+ end
@@ -0,0 +1,58 @@
1
+ require 'deas-erubis/source'
2
+
3
+ module Deas; end
4
+ module Deas::Erubis
5
+
6
+ module TemplateHelpers
7
+
8
+ def self.included(receiver)
9
+ receiver.class_eval{ include Methods }
10
+ end
11
+
12
+ module Methods
13
+
14
+ def partial(*args)
15
+ @deas_source.partial(*args)
16
+ end
17
+
18
+ def capture_partial(*args, &content)
19
+ _erb_buffer @deas_source.partial(*args, &Proc.new{ _erb_capture(&content) })
20
+ end
21
+
22
+ private
23
+
24
+ def _erb_capture(&content)
25
+ begin
26
+ # copy original buffer state
27
+ orig_buf_value = _erb_bufvar
28
+ instance_variable_set(_erb_bufvar_name, "\n")
29
+
30
+ # evaluate the given content
31
+ result = instance_eval(&content)
32
+ new_buf_value = _erb_bufvar
33
+
34
+ # return result if nothing buffered; otherwise return what was buffered
35
+ new_buf_value == "\n" ? "\n#{result}" : new_buf_value
36
+ ensure
37
+ # reset buffer to original state
38
+ instance_variable_set(_erb_bufvar_name, orig_buf_value)
39
+ end
40
+ end
41
+
42
+ def _erb_buffer(content)
43
+ _erb_bufvar << content
44
+ end
45
+
46
+ def _erb_bufvar
47
+ instance_variable_get(_erb_bufvar_name)
48
+ end
49
+
50
+ def _erb_bufvar_name
51
+ Deas::Erubis::Source::BUFVAR_NAME
52
+ end
53
+
54
+ end
55
+
56
+ end
57
+
58
+ end
@@ -0,0 +1,4 @@
1
+ module Deas; end
2
+ module Deas::Erubis
3
+ VERSION = "0.1.0"
4
+ end
@@ -0,0 +1,53 @@
1
+ require 'deas/template_engine'
2
+ require 'erubis'
3
+
4
+ require 'deas-erubis/version'
5
+ require 'deas-erubis/source'
6
+
7
+ module Deas::Erubis
8
+
9
+ class TemplateEngine < Deas::TemplateEngine
10
+
11
+ DEFAULT_HANDLER_LOCAL = 'view'.freeze
12
+ DEFAULT_LOGGER_LOCAL = 'logger'.freeze
13
+
14
+ def erb_source
15
+ @erb_source ||= Source.new(self.source_path, {
16
+ :eruby => self.opts['eruby'],
17
+ :cache => self.opts['cache'],
18
+ :deas_source => self.opts['deas_template_source'],
19
+ :default_locals => { self.erb_logger_local => self.logger }
20
+ })
21
+ end
22
+
23
+ def erb_handler_local
24
+ @erb_handler_local ||= (self.opts['handler_local'] || DEFAULT_HANDLER_LOCAL)
25
+ end
26
+
27
+ def erb_logger_local
28
+ @erb_logger_local ||= (self.opts['logger_local'] || DEFAULT_LOGGER_LOCAL)
29
+ end
30
+
31
+ # render the template including the handler as a local
32
+ def render(template_name, view_handler, locals, &content)
33
+ self.erb_source.render(template_name, render_locals(view_handler, locals), &content)
34
+ end
35
+
36
+ # render the template against the given locals
37
+ def partial(template_name, locals, &content)
38
+ self.erb_source.render(template_name, locals, &content)
39
+ end
40
+
41
+ def compile(template_name, compiled_content)
42
+ self.erb_source.compile(template_name, compiled_content)
43
+ end
44
+
45
+ private
46
+
47
+ def render_locals(view_handler, locals)
48
+ { self.erb_handler_local => view_handler }.merge(locals)
49
+ end
50
+
51
+ end
52
+
53
+ end
data/log/.gitkeep ADDED
File without changes
data/test/helper.rb ADDED
@@ -0,0 +1,17 @@
1
+ # this file is automatically required when you run `assert`
2
+ # put any test helpers here
3
+
4
+ require 'pathname'
5
+
6
+ # add the root dir to the load path
7
+ ROOT = Pathname.new(File.expand_path("../..", __FILE__))
8
+ $LOAD_PATH.unshift(ROOT.to_s)
9
+
10
+ TEST_SUPPORT_PATH = ROOT.join('test/support')
11
+ TEMPLATE_ROOT = TEST_SUPPORT_PATH.join('templates')
12
+ TEMPLATE_CACHE_ROOT = ROOT.join('tmp/templates')
13
+
14
+ # require pry for debugging (`binding.pry`)
15
+ require 'pry'
16
+
17
+ require 'test/support/factory'
@@ -0,0 +1,84 @@
1
+ require 'assert/factory'
2
+
3
+ module Factory
4
+ extend Assert::Factory
5
+
6
+ def self.template_root
7
+ TEMPLATE_ROOT.to_s
8
+ end
9
+
10
+ def self.template_file(name)
11
+ TEMPLATE_ROOT.join(name).to_s
12
+ end
13
+
14
+ def self.basic_erb_rendered(locals)
15
+ "<h1>name: #{locals['name']}</h1>\n"\
16
+ "<h2>local1: #{locals['local1']}</h2>\n"
17
+ end
18
+
19
+ def self.yield_erb_rendered(locals, &content)
20
+ "<h1>name: #{locals['name']}</h1>\n"\
21
+ "<h2>local1: #{locals['local1']}</h2>\n"\
22
+ "<div>\n"\
23
+ " #{content.call}\n"\
24
+ "</div>\n"
25
+ end
26
+
27
+ def self.view_erb_rendered(engine, view_handler, locals)
28
+ "<h1>name: #{view_handler.name}</h1>\n"\
29
+ "<h2>local1: #{locals['local1']}</h2>\n"\
30
+ "<p>id: #{view_handler.identifier}</p>\n"\
31
+ "<p>logger: #{engine.logger.to_s}</p>\n"
32
+ end
33
+
34
+ def self.yield_view_erb_rendered(engine, view_handler, locals, &content)
35
+ "<h1>name: #{view_handler.name}</h1>\n"\
36
+ "<h2>local1: #{locals['local1']}</h2>\n"\
37
+ "<p>id: #{view_handler.identifier}</p>\n"\
38
+ "<p>logger: #{engine.logger.to_s}</p>\n"\
39
+ "<div>\n"\
40
+ " #{content.call}\n"\
41
+ "</div>\n"
42
+ end
43
+
44
+ def self.partial_erb_rendered(engine, locals)
45
+ "<h1>local1: #{locals['local1']}</h1>\n"\
46
+ "<p>logger: #{engine.logger.to_s}</p>\n"
47
+ end
48
+
49
+ def self.yield_partial_erb_rendered(engine, locals, &content)
50
+ "<h1>local1: #{locals['local1']}</h1>\n"\
51
+ "<p>logger: #{engine.logger.to_s}</p>\n"\
52
+ "<div>\n"\
53
+ " #{content.call}\n"\
54
+ "</div>\n"
55
+ end
56
+
57
+ def self.partial_with_partial_erb_rendered(engine, locals)
58
+ "<div>\n"\
59
+ " <h1>local1: #{locals['local1']}</h1>\n"\
60
+ "<p>logger: #{engine.logger.to_s}</p>\n\n"\
61
+ "</div>\n"
62
+ end
63
+
64
+ def self.partial_with_capture_partial_erb_rendered(engine, locals)
65
+ "<div>\n"\
66
+ "<h1>local1: #{locals['local1']}</h1>\n"\
67
+ "<p>logger: #{engine.logger.to_s}</p>\n"\
68
+ "<div>\n"\
69
+ " \n"\
70
+ " <span>some content</span>\n"\
71
+ "\n"\
72
+ "</div>\n"\
73
+ "<h1>local1: #{locals['local1']}</h1>\n"\
74
+ "<p>logger: #{engine.logger.to_s}</p>\n"\
75
+ "</div>\n"
76
+ end
77
+
78
+ def self.compile_erb_rendered(engine)
79
+ "<h1>compile</h1>\n"\
80
+ "<p>2</p>\n"\
81
+ "<p>logger: #{engine.logger.to_s}</p>\n"
82
+ end
83
+
84
+ end
@@ -0,0 +1,2 @@
1
+ <h1>local1: <%= local1 %></h1>
2
+ <p>logger: <%= logger %></p>
@@ -0,0 +1,5 @@
1
+ <h1>local1: <%= local1 %></h1>
2
+ <p>logger: <%= logger %></p>
3
+ <div>
4
+ <%= yield %>
5
+ </div>
@@ -0,0 +1,2 @@
1
+ <h1>name: <%= name %></h1>
2
+ <h2>local1: <%= local1 %></h2>
@@ -0,0 +1,3 @@
1
+ <h1>compile</h1>
2
+ <p><%= 1 + 1 %></p>
3
+ <p>logger: <%= logger %></p>
@@ -0,0 +1,4 @@
1
+ <h1>name: <%= view.name %></h1>
2
+ <h2>local1: <%= local1 %></h2>
3
+ <p>id: <%= view.identifier %></p>
4
+ <p>logger: <%= logger %></p>
@@ -0,0 +1,6 @@
1
+ <div>
2
+ <% capture_partial '_yield_partial', 'local1' => local1 do %>
3
+ <span>some content</span>
4
+ <% end %>
5
+ <% capture_partial '_partial', 'local1' => local1 %>
6
+ </div>
@@ -0,0 +1,3 @@
1
+ <div>
2
+ <%= partial '_partial', 'local1' => local1 %>
3
+ </div>
@@ -0,0 +1,5 @@
1
+ <h1>name: <%= name %></h1>
2
+ <h2>local1: <%= local1 %></h2>
3
+ <div>
4
+ <%= yield %>
5
+ </div>
@@ -0,0 +1,7 @@
1
+ <h1>name: <%= view.name %></h1>
2
+ <h2>local1: <%= local1 %></h2>
3
+ <p>id: <%= view.identifier %></p>
4
+ <p>logger: <%= logger %></p>
5
+ <div>
6
+ <%= yield %>
7
+ </div>
@@ -0,0 +1,74 @@
1
+ require 'assert'
2
+ require 'deas-erubis'
3
+
4
+ require 'deas/template_source'
5
+
6
+ class Deas::Erubis::TemplateEngine
7
+
8
+ class SystemTests < Assert::Context
9
+ desc "Deas::Erubis::TemplateEngine"
10
+ setup do
11
+ @view = OpenStruct.new({
12
+ :identifier => Factory.integer,
13
+ :name => Factory.string
14
+ })
15
+ @locals = { 'local1' => Factory.string }
16
+ @content = Proc.new{ "<span>some content</span>" }
17
+
18
+ @engine = Deas::Erubis::TemplateEngine.new('source_path' => TEMPLATE_ROOT)
19
+ end
20
+ subject{ @engine }
21
+
22
+ should "render templates" do
23
+ exp = Factory.view_erb_rendered(subject, @view, @locals)
24
+ assert_equal exp, subject.render('view', @view, @locals)
25
+ end
26
+
27
+ should "render templates yielding to given content blocks" do
28
+ exp = Factory.yield_view_erb_rendered(subject, @view, @locals, &@content)
29
+ assert_equal exp, subject.render('yield_view', @view, @locals, &@content)
30
+ end
31
+
32
+ should "render partial templates" do
33
+ exp = Factory.partial_erb_rendered(subject, @locals)
34
+ assert_equal exp, subject.partial('_partial', @locals)
35
+ end
36
+
37
+ should "render partial templates yielding to given content blocks" do
38
+ exp = Factory.yield_partial_erb_rendered(subject, @locals, &@content)
39
+ assert_equal exp, subject.partial('_yield_partial', @locals, &@content)
40
+ end
41
+
42
+ should "compile raw template markup" do
43
+ file_name = 'compile'
44
+ file_path = TEMPLATE_ROOT.join("#{file_name}#{Deas::Erubis::Source::EXT}").to_s
45
+ file_content = File.read(file_path)
46
+
47
+ exp = Factory.compile_erb_rendered(subject)
48
+ assert_equal exp, subject.compile(file_name, file_content)
49
+ end
50
+
51
+ end
52
+
53
+ class TemplateHelperTests < SystemTests
54
+ desc "template helpers"
55
+ setup do
56
+ @deas_source = Deas::TemplateSource.new(TEMPLATE_ROOT).tap do |s|
57
+ s.engine 'erb', Deas::Erubis::TemplateEngine
58
+ end
59
+ @engine = @deas_source.engines['erb']
60
+ end
61
+
62
+ should "render partials" do
63
+ exp = Factory.partial_with_partial_erb_rendered(subject, @locals)
64
+ assert_equal exp, subject.partial('with_partial', @locals)
65
+ end
66
+
67
+ should "capture render partials" do
68
+ exp = Factory.partial_with_capture_partial_erb_rendered(subject, @locals).to_s
69
+ assert_equal exp, subject.partial('with_capture_partial', @locals)
70
+ end
71
+
72
+ end
73
+
74
+ end
@@ -0,0 +1,271 @@
1
+ require 'assert'
2
+ require 'deas-erubis/source'
3
+
4
+ require 'erubis'
5
+
6
+ class Deas::Erubis::Source
7
+
8
+ class UnitTests < Assert::Context
9
+ desc "Deas::Erubis::Source"
10
+ setup do
11
+ @source_class = Deas::Erubis::Source
12
+ end
13
+ subject{ @source_class }
14
+
15
+ should "know its extensions" do
16
+ assert_equal '.erb', subject::EXT
17
+ assert_equal '.cache', subject::CACHE_EXT
18
+ end
19
+
20
+ should "know the bufvar name to use" do
21
+ assert_equal '@_erb_buf', subject::BUFVAR_NAME
22
+ end
23
+
24
+ should "know its default eruby class" do
25
+ assert_equal ::Erubis::Eruby, subject::DEFAULT_ERUBY
26
+ end
27
+
28
+ end
29
+
30
+ class InitTests < UnitTests
31
+ desc "when init"
32
+ setup do
33
+ @root = Factory.template_root
34
+ @source = @source_class.new(@root, {})
35
+ end
36
+ subject{ @source }
37
+
38
+ should have_readers :root, :cache_root, :eruby_class, :context_class
39
+ should have_imeths :eruby, :render, :compile
40
+
41
+ should "know its root" do
42
+ assert_equal @root, subject.root.to_s
43
+ end
44
+
45
+ should "default its eruby class" do
46
+ assert_equal Deas::Erubis::Source::DEFAULT_ERUBY, subject.eruby_class
47
+ end
48
+
49
+ should "optionally take a custom eruby class" do
50
+ eruby = 'some-eruby-class'
51
+ source = @source_class.new(@root, :eruby => eruby)
52
+ assert_equal eruby, source.eruby_class
53
+ end
54
+
55
+ should "build eruby instances for a given template file" do
56
+ assert_kind_of subject.eruby_class, subject.eruby('basic')
57
+ end
58
+
59
+ should "build its eruby instances with the correct bufvar name" do
60
+ exp = Deas::Erubis::Source::BUFVAR_NAME
61
+ assert_equal exp, subject.eruby('basic').instance_variable_get('@bufvar')
62
+ end
63
+
64
+ should "default its cache root" do
65
+ assert_equal Pathname.new('').to_s, subject.cache_root.to_s
66
+ end
67
+
68
+ should "use the root as its cache root if :cache opt is `true`" do
69
+ source = @source_class.new(@root, :cache => true)
70
+ assert_equal @root.to_s, source.cache_root.to_s
71
+ end
72
+
73
+ should "optionally use a custom cache root" do
74
+ source = @source_class.new(@root, :cache => TEMPLATE_CACHE_ROOT)
75
+ assert_equal TEMPLATE_CACHE_ROOT.to_s, source.cache_root.to_s
76
+ end
77
+
78
+ should "create the cache root if it doesn't exist already" do
79
+ FileUtils.rm_rf(TEMPLATE_CACHE_ROOT) if TEMPLATE_CACHE_ROOT.exist?
80
+ source = @source_class.new(@root, :cache => TEMPLATE_CACHE_ROOT)
81
+ assert_file_exists TEMPLATE_CACHE_ROOT.to_s
82
+ end
83
+
84
+ should "know its context class" do
85
+ assert_instance_of ::Class, subject.context_class
86
+ end
87
+
88
+ should "mixin template helpers to its context class" do
89
+ assert_includes Deas::Erubis::TemplateHelpers, subject.context_class
90
+
91
+ context = subject.context_class.new('deas-source', {})
92
+ assert_responds_to :partial, context
93
+ assert_responds_to :capture_partial, context
94
+ end
95
+
96
+ should "optionally take and apply default locals to its context class" do
97
+ local_name, local_val = [Factory.string, Factory.string]
98
+ source = @source_class.new(@root, {
99
+ :default_locals => { local_name => local_val }
100
+ })
101
+ context = source.context_class.new('deas-source', {})
102
+
103
+ assert_responds_to local_name, context
104
+ assert_equal local_val, context.send(local_name)
105
+ end
106
+
107
+ should "apply custom locals to its context class instances on init" do
108
+ local_name, local_val = [Factory.string, Factory.string]
109
+ context = subject.context_class.new('deas-source', local_name => local_val)
110
+
111
+ assert_responds_to local_name, context
112
+ assert_equal local_val, context.send(local_name)
113
+ end
114
+
115
+ should "set any deas source given to its context class as in ivar on init" do
116
+ deas_source = 'a-deas-source'
117
+ context = subject.context_class.new(deas_source, {})
118
+
119
+ assert_equal deas_source, context.instance_variable_get('@deas_source')
120
+ end
121
+
122
+ end
123
+
124
+ class RenderSetupTests < InitTests
125
+ setup do
126
+ @file_locals = {
127
+ 'name' => Factory.string,
128
+ 'local1' => Factory.integer
129
+ }
130
+ end
131
+ teardown do
132
+ root = TEMPLATE_ROOT.join("*#{@source_class::CACHE_EXT}").to_s
133
+ Dir.glob(root).each{ |f| FileUtils.rm_f(f) }
134
+ root = TEMPLATE_CACHE_ROOT.join("*#{@source_class::CACHE_EXT}").to_s
135
+ Dir.glob(root).each{ |f| FileUtils.rm_f(f) }
136
+ end
137
+
138
+ end
139
+
140
+ class RenderTests < RenderSetupTests
141
+ desc "`render` method"
142
+ setup do
143
+ @file_name = "basic"
144
+ end
145
+
146
+ should "render a template for the given file name and return its data" do
147
+ exp = Factory.basic_erb_rendered(@file_locals)
148
+ assert_equal exp, subject.render(@file_name, @file_locals)
149
+ end
150
+
151
+ should "pass its deas source to its context class" do
152
+ deas_source = 'a-deas-source'
153
+ source = @source_class.new(@root, :deas_source => deas_source)
154
+ context_class = nil
155
+ Assert.stub(source.context_class, :new) do |s, l|
156
+ context_class = ContextClassSpy.new(s, l)
157
+ end
158
+ source.render(@file_name, @file_locals)
159
+
160
+ assert_equal deas_source, context_class.deas_source
161
+ end
162
+
163
+ end
164
+
165
+ class RenderEnabledCacheTests < RenderTests
166
+ desc "when caching is enabled"
167
+ setup do
168
+ @source = @source_class.new(@root, :cache => true)
169
+ end
170
+
171
+ should "cache templates in the root (cache root) alongside the source" do
172
+ f = "#{@file_name}#{@source_class::EXT}#{@source_class::CACHE_EXT}"
173
+ cache_file = subject.root.join(f)
174
+
175
+ assert_not_file_exists cache_file
176
+ subject.render(@file_name, @file_locals)
177
+ assert_file_exists cache_file
178
+ end
179
+
180
+ end
181
+
182
+ class RenderCustomCacheTests < RenderTests
183
+ desc "when caching is enabled on a custom cache root"
184
+ setup do
185
+ @source = @source_class.new(@root, :cache => TEMPLATE_CACHE_ROOT)
186
+ end
187
+
188
+ should "cache templates in the cache root" do
189
+ f = "#{@file_name}#{@source_class::EXT}#{@source_class::CACHE_EXT}"
190
+ cache_file = TEMPLATE_CACHE_ROOT.join(f)
191
+
192
+ assert_not_file_exists cache_file
193
+ subject.render(@file_name, @file_locals)
194
+ assert_file_exists cache_file
195
+ end
196
+
197
+ end
198
+
199
+ class RenderNoCacheTests < RenderTests
200
+ desc "when caching is disabled"
201
+ setup do
202
+ @source = @source_class.new(@root, :cache => false)
203
+ end
204
+
205
+ should "not cache templates" do
206
+ f = "#{@file_name}#{@source_class::EXT}#{@source_class::CACHE_EXT}"
207
+ cache_file = subject.root.join(f)
208
+
209
+ assert_not_file_exists cache_file
210
+ subject.render(@file_name, @file_locals)
211
+ assert_not_file_exists cache_file
212
+ end
213
+
214
+ end
215
+
216
+ class RenderContentTests < RenderTests
217
+ desc "when yielding to a given content block"
218
+ setup do
219
+ @file_name = "yield"
220
+ @content = Proc.new{ "<span>some content</span>" }
221
+ end
222
+
223
+ should "render the template for the given file name and return its data" do
224
+ exp = Factory.yield_erb_rendered(@file_locals, &@content)
225
+ assert_equal exp, subject.render(@file_name, @file_locals, &@content)
226
+ end
227
+
228
+ end
229
+
230
+ class CompileTests < RenderSetupTests
231
+ desc "`compile` method"
232
+
233
+ should "compile raw content file name and return its data" do
234
+ raw = "<p><%= 1 + 1 %></p>"
235
+ exp = "<p>2</p>"
236
+ assert_equal exp, subject.compile('compile', raw)
237
+ end
238
+
239
+ end
240
+
241
+ class DefaultSource < UnitTests
242
+ desc "DefaultSource"
243
+ setup do
244
+ @source = Deas::Erubis::DefaultSource.new
245
+ end
246
+ subject{ @source }
247
+
248
+ should "be a Source" do
249
+ assert_kind_of @source_class, subject
250
+ end
251
+
252
+ should "use `/` as its root" do
253
+ assert_equal '/', subject.root.to_s
254
+ end
255
+
256
+ end
257
+
258
+ class ContextClassSpy
259
+ attr_reader :deas_source
260
+ def initialize(deas_source, locals)
261
+ @deas_source = deas_source
262
+ metaclass = class << self; self; end
263
+ metaclass.class_eval do
264
+ locals.each do |key, value|
265
+ define_method(key){ value }
266
+ end
267
+ end
268
+ end
269
+ end
270
+
271
+ end
@@ -0,0 +1,74 @@
1
+ require 'assert'
2
+ require 'deas-erubis'
3
+
4
+ require 'deas/template_engine'
5
+ require 'deas-erubis/source'
6
+
7
+ class Deas::Erubis::TemplateEngine
8
+
9
+ class UnitTests < Assert::Context
10
+ desc "Deas::Erubis::TemplateEngine"
11
+ setup do
12
+ @engine = Deas::Erubis::TemplateEngine.new({
13
+ 'source_path' => TEST_SUPPORT_PATH
14
+ })
15
+ end
16
+ subject{ @engine }
17
+
18
+ should have_imeths :erb_source, :erb_handler_local, :erb_logger_local
19
+ should have_imeths :render, :partial
20
+
21
+ should "be a Deas template engine" do
22
+ assert_kind_of Deas::TemplateEngine, subject
23
+ end
24
+
25
+ should "memoize its erb source" do
26
+ assert_kind_of Deas::Erubis::Source, subject.erb_source
27
+ assert_equal subject.source_path, subject.erb_source.root
28
+ assert_same subject.erb_source, subject.erb_source
29
+ end
30
+
31
+ should "allow custom eruby classes on its source" do
32
+ custom_eruby = 'some-eruby'
33
+ engine = Deas::Erubis::TemplateEngine.new('eruby' => custom_eruby)
34
+ assert_equal custom_eruby, engine.erb_source.eruby_class
35
+ end
36
+
37
+ should "allow custom cache roots on its source" do
38
+ engine = Deas::Erubis::TemplateEngine.new('cache' => TEMPLATE_CACHE_ROOT)
39
+ assert_equal TEMPLATE_CACHE_ROOT.to_s, engine.erb_source.cache_root.to_s
40
+ end
41
+
42
+ should "pass any given deas template source to its source" do
43
+ deas_source = 'a-deas-source'
44
+ source_opts = nil
45
+
46
+ Assert.stub(Deas::Erubis::Source, :new){ |root, opts| source_opts = opts }
47
+ Deas::Erubis::TemplateEngine.new('deas_template_source' => deas_source).erb_source
48
+
49
+ assert_equal deas_source, source_opts[:deas_source]
50
+ end
51
+
52
+ should "use 'view' as the handler local name by default" do
53
+ assert_equal 'view', subject.erb_handler_local
54
+ end
55
+
56
+ should "allow custom handler local names" do
57
+ handler_local = Factory.string
58
+ engine = Deas::Erubis::TemplateEngine.new('handler_local' => handler_local)
59
+ assert_equal handler_local, engine.erb_handler_local
60
+ end
61
+
62
+ should "use 'logger' as the logger local name by default" do
63
+ assert_equal 'logger', subject.erb_logger_local
64
+ end
65
+
66
+ should "allow custom logger local names" do
67
+ logger_local = Factory.string
68
+ engine = Deas::Erubis::TemplateEngine.new('logger_local' => logger_local)
69
+ assert_equal logger_local, engine.erb_logger_local
70
+ end
71
+
72
+ end
73
+
74
+ end
data/tmp/.gitkeep ADDED
File without changes
metadata ADDED
@@ -0,0 +1,149 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: deas-erubis
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Kelly Redding
14
+ - Collin Redding
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2015-01-08 00:00:00 Z
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ requirement: &id001 !ruby/object:Gem::Requirement
23
+ none: false
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ hash: 27
28
+ segments:
29
+ - 2
30
+ - 12
31
+ version: "2.12"
32
+ type: :development
33
+ name: assert
34
+ version_requirements: *id001
35
+ prerelease: false
36
+ - !ruby/object:Gem::Dependency
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ~>
41
+ - !ruby/object:Gem::Version
42
+ hash: 49
43
+ segments:
44
+ - 0
45
+ - 29
46
+ version: "0.29"
47
+ type: :runtime
48
+ name: deas
49
+ version_requirements: *id002
50
+ prerelease: false
51
+ - !ruby/object:Gem::Dependency
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ type: :runtime
62
+ name: erubis
63
+ version_requirements: *id003
64
+ prerelease: false
65
+ description: Deas template engine for rendering erb templates using Erubis
66
+ email:
67
+ - kelly@kellyredding.com
68
+ - collin.redding@me.com
69
+ executables: []
70
+
71
+ extensions: []
72
+
73
+ extra_rdoc_files: []
74
+
75
+ files:
76
+ - .gitignore
77
+ - Gemfile
78
+ - LICENSE.txt
79
+ - README.md
80
+ - Rakefile
81
+ - deas-erubis.gemspec
82
+ - lib/deas-erubis.rb
83
+ - lib/deas-erubis/source.rb
84
+ - lib/deas-erubis/template_helpers.rb
85
+ - lib/deas-erubis/version.rb
86
+ - log/.gitkeep
87
+ - test/helper.rb
88
+ - test/support/factory.rb
89
+ - test/support/templates/_partial.erb
90
+ - test/support/templates/_yield_partial.erb
91
+ - test/support/templates/basic.erb
92
+ - test/support/templates/compile.erb
93
+ - test/support/templates/view.erb
94
+ - test/support/templates/with_capture_partial.erb
95
+ - test/support/templates/with_partial.erb
96
+ - test/support/templates/yield.erb
97
+ - test/support/templates/yield_view.erb
98
+ - test/system/template_engine_tests.rb
99
+ - test/unit/source_tests.rb
100
+ - test/unit/template_engine_tests.rb
101
+ - tmp/.gitkeep
102
+ homepage: http://github.com/redding/deas-erubis
103
+ licenses:
104
+ - MIT
105
+ post_install_message:
106
+ rdoc_options: []
107
+
108
+ require_paths:
109
+ - lib
110
+ required_ruby_version: !ruby/object:Gem::Requirement
111
+ none: false
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ hash: 3
116
+ segments:
117
+ - 0
118
+ version: "0"
119
+ required_rubygems_version: !ruby/object:Gem::Requirement
120
+ none: false
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ hash: 3
125
+ segments:
126
+ - 0
127
+ version: "0"
128
+ requirements: []
129
+
130
+ rubyforge_project:
131
+ rubygems_version: 1.8.25
132
+ signing_key:
133
+ specification_version: 3
134
+ summary: Deas template engine for rendering erb templates using Erubis
135
+ test_files:
136
+ - test/helper.rb
137
+ - test/support/factory.rb
138
+ - test/support/templates/_partial.erb
139
+ - test/support/templates/_yield_partial.erb
140
+ - test/support/templates/basic.erb
141
+ - test/support/templates/compile.erb
142
+ - test/support/templates/view.erb
143
+ - test/support/templates/with_capture_partial.erb
144
+ - test/support/templates/with_partial.erb
145
+ - test/support/templates/yield.erb
146
+ - test/support/templates/yield_view.erb
147
+ - test/system/template_engine_tests.rb
148
+ - test/unit/source_tests.rb
149
+ - test/unit/template_engine_tests.rb