stache 0.2.2 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/CHANGELOG.md +10 -0
  2. data/README.md +32 -7
  3. data/lib/stache.rb +1 -3
  4. data/lib/stache/asset_helper.rb +15 -22
  5. data/lib/stache/config.rb +11 -9
  6. data/lib/stache/handlebars.rb +7 -0
  7. data/lib/stache/handlebars/handler.rb +80 -0
  8. data/lib/stache/handlebars/view.rb +14 -0
  9. data/lib/stache/mustache.rb +7 -0
  10. data/lib/stache/mustache/handler.rb +70 -0
  11. data/lib/stache/mustache/view.rb +37 -0
  12. data/lib/stache/version.rb +1 -1
  13. data/spec/controllers/handlebars_controller_spec.rb +35 -0
  14. data/spec/controllers/stache_controller_spec.rb +17 -5
  15. data/spec/dummy/app/assets/stylesheets/test.css +3 -0
  16. data/spec/dummy/app/controllers/handlebars_controller.rb +18 -0
  17. data/spec/dummy/app/controllers/stache_controller.rb +8 -3
  18. data/spec/dummy/app/helpers/application_helper.rb +4 -0
  19. data/spec/dummy/app/views/handlebars/_eaten_by_a.html.hbs +1 -0
  20. data/spec/dummy/app/views/handlebars/index.html.hbs +1 -0
  21. data/spec/dummy/app/views/handlebars/with_helpers.html.hbs +3 -0
  22. data/spec/dummy/app/views/handlebars/with_partials.html.hbs +3 -0
  23. data/spec/dummy/app/views/stache/with_asset_helpers.html.mustache +4 -0
  24. data/spec/dummy/config/application.rb +3 -0
  25. data/spec/dummy/config/initializers/stache.rb +2 -0
  26. data/spec/dummy/config/routes.rb +5 -53
  27. data/spec/dummy/lib/with_asset_helpers.rb +11 -0
  28. data/spec/spec_helper.rb +1 -1
  29. data/spec/stache/asset_helper_spec.rb +41 -39
  30. data/spec/stache/config_spec.rb +4 -6
  31. data/spec/stache/handlebars/handlebars_spec.rb +37 -0
  32. data/spec/stache/handlebars/profile_autoload.rb +6 -0
  33. data/spec/stache/handlebars/view_spec.rb +11 -0
  34. data/spec/stache/{handler_spec.rb → mustache/handler_spec.rb} +8 -8
  35. data/spec/stache/{profile_autoload.rb → mustache/profile_autoload.rb} +1 -1
  36. data/spec/stache/mustache/view_spec.rb +11 -0
  37. data/stache.gemspec +3 -5
  38. metadata +50 -22
  39. data/lib/stache/handler.rb +0 -68
  40. data/lib/stache/view.rb +0 -38
  41. data/spec/stache/view_spec.rb +0 -9
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe HandlebarsController do
4
+ render_views
5
+
6
+ before do
7
+ Stache.template_base_path = ::Rails.root.join('app', 'views')
8
+ end
9
+
10
+ it "can get to index and render a Handlebars" do
11
+ get :index
12
+ assert_response 200
13
+
14
+ response.should render_template 'index'
15
+ response.body.should =~ /Hello, Matt!/
16
+ end
17
+
18
+ it "correctly renders partials" do
19
+ get :with_partials
20
+ assert_response 200
21
+
22
+ response.body.should =~ /Grue/
23
+ # puts response.body
24
+ end
25
+
26
+ it "correctly uses helpers" do
27
+ get :with_helpers
28
+ assert_response 200
29
+
30
+ response.body.should =~ /Here's an image_path=\/assets\/image\.png/
31
+ response.body.should =~ /Here's a capitalized string: Lowercase/
32
+ end
33
+
34
+
35
+ end
@@ -2,7 +2,11 @@ require 'spec_helper'
2
2
 
3
3
  describe StacheController do
4
4
  render_views
5
-
5
+
6
+ before do
7
+ Stache.template_base_path = ::Rails.root.join('app', 'views')
8
+ end
9
+
6
10
  it "can get to index and render a Mustache" do
7
11
  get :index
8
12
  assert_response 200
@@ -10,14 +14,22 @@ describe StacheController do
10
14
  response.should render_template 'index' # view
11
15
  response.body.should =~ /Hello, Matt!/
12
16
  end
13
-
17
+
14
18
  it "correctly renders partials" do
15
19
  get :with_partials
16
20
  assert_response 200
17
-
21
+
18
22
  response.body.should =~ /Grue/
19
23
  # puts response.body
20
24
  end
21
-
22
-
25
+
26
+ it "correctly uses the asset helpers" do
27
+ get :with_asset_helpers
28
+ assert_response 200
29
+
30
+ response.body.should =~ /Here's an image_path=\/assets\/image\.png/
31
+ response.body.should =~ /link href="\/assets\/test\.css"/
32
+ end
33
+
34
+
23
35
  end
@@ -0,0 +1,3 @@
1
+ body {
2
+ margin: 0;
3
+ }
@@ -0,0 +1,18 @@
1
+ class HandlebarsController < ApplicationController
2
+
3
+ def index
4
+ @user = params[:user] || "Matt"
5
+ # index.html.hbs
6
+ end
7
+
8
+ def with_partials
9
+ @user = params[:user] || "Matt"
10
+ @thing = "Grue"
11
+ end
12
+
13
+ def with_helpers
14
+ @image = "image.png"
15
+ @some_text = "lowercase"
16
+ end
17
+
18
+ end
@@ -1,13 +1,18 @@
1
1
  class StacheController < ApplicationController
2
-
2
+
3
3
  def index
4
4
  @user = params[:user] || "Matt"
5
5
  # index.html.mustache
6
6
  end
7
-
7
+
8
8
  def with_partials
9
9
  @user = params[:user] || "Matt"
10
10
  @thing = "Grue"
11
11
  end
12
-
12
+
13
+ def with_asset_helpers
14
+ require 'with_asset_helpers'
15
+ # with_asset_helpers.html.mustache
16
+ end
17
+
13
18
  end
@@ -1,2 +1,6 @@
1
1
  module ApplicationHelper
2
+
3
+ def capitalize string
4
+ string.capitalize if string
5
+ end
2
6
  end
@@ -0,0 +1 @@
1
+ <b>{{thing}}</b>
@@ -0,0 +1 @@
1
+ Hello, {{user}}!
@@ -0,0 +1,3 @@
1
+ Here's an image_path={{image_path image}}
2
+
3
+ Here's a capitalized string: {{capitalize some_text}}
@@ -0,0 +1,3 @@
1
+ Unfortunately, {{user}} was eaten by a:
2
+
3
+ {{> eaten_by_a }}
@@ -0,0 +1,4 @@
1
+ Here's an image_path={{my_image}}
2
+
3
+ Here's a stylesheet link tag:
4
+ {{{my_styles}}}
@@ -5,6 +5,7 @@ require "active_model/railtie"
5
5
  require "action_controller/railtie"
6
6
  require "action_view/railtie"
7
7
  require "action_mailer/railtie"
8
+ require "sprockets/railtie"
8
9
 
9
10
  Bundler.require
10
11
 
@@ -40,5 +41,7 @@ module Dummy
40
41
 
41
42
  # Configure sensitive parameters which will be filtered from the log file.
42
43
  config.filter_parameters += [:password]
44
+
45
+ config.assets.enabled = true
43
46
  end
44
47
  end
@@ -1,3 +1,5 @@
1
1
  Stache.configure do |config|
2
2
  config.template_base_path = Rails.root.join('app', 'views')
3
+ config.use :mustache
4
+ config.use :handlebars
3
5
  end
@@ -1,61 +1,13 @@
1
1
  Dummy::Application.routes.draw do
2
2
  get 'stache', :to => 'stache#index', :as => 'stache'
3
-
4
- get 'stache/with_partials', :to => 'stache#with_partials'
5
- # The priority is based upon order of creation:
6
- # first created -> highest priority.
7
-
8
- # Sample of regular route:
9
- # match 'products/:id' => 'catalog#view'
10
- # Keep in mind you can assign values other than :controller and :action
11
-
12
- # Sample of named route:
13
- # match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
14
- # This route can be invoked with purchase_url(:id => product.id)
15
-
16
- # Sample resource route (maps HTTP verbs to controller actions automatically):
17
- # resources :products
18
3
 
19
- # Sample resource route with options:
20
- # resources :products do
21
- # member do
22
- # get 'short'
23
- # post 'toggle'
24
- # end
25
- #
26
- # collection do
27
- # get 'sold'
28
- # end
29
- # end
30
-
31
- # Sample resource route with sub-resources:
32
- # resources :products do
33
- # resources :comments, :sales
34
- # resource :seller
35
- # end
36
-
37
- # Sample resource route with more complex sub-resources
38
- # resources :products do
39
- # resources :comments
40
- # resources :sales do
41
- # get 'recent', :on => :collection
42
- # end
43
- # end
4
+ get 'stache/with_partials', :to => 'stache#with_partials'
44
5
 
45
- # Sample resource route within a namespace:
46
- # namespace :admin do
47
- # # Directs /admin/products/* to Admin::ProductsController
48
- # # (app/controllers/admin/products_controller.rb)
49
- # resources :products
50
- # end
6
+ get 'stache/with_asset_helpers', :to => 'stache#with_asset_helpers'
51
7
 
52
- # You can have the root of your site routed with "root"
53
- # just remember to delete public/index.html.
54
- # root :to => "welcome#index"
8
+ get 'handlebars', :to => 'handlebars#index', :as => 'handlebars'
55
9
 
56
- # See how all your routes lay out with "rake routes"
10
+ get 'handlebars/with_partials', :to => 'handlebars#with_partials'
57
11
 
58
- # This is a legacy wild controller route that's not recommended for RESTful applications.
59
- # Note: This route will make all actions in every controller accessible via GET requests.
60
- # match ':controller(/:action(/:id(.:format)))'
12
+ get 'handlebars/with_helpers', :to => 'handlebars#with_helpers'
61
13
  end
@@ -0,0 +1,11 @@
1
+ class Stache::WithAssetHelpers < Stache::Mustache::View
2
+
3
+ def my_image
4
+ @my_image ||= image_path("image.png")
5
+ end
6
+
7
+ def my_styles
8
+ @my_styles ||= stylesheet_link_tag("test")
9
+ end
10
+
11
+ end
data/spec/spec_helper.rb CHANGED
@@ -29,5 +29,5 @@ require 'rspec/rails'
29
29
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
30
30
 
31
31
  RSpec.configure do |config|
32
-
32
+
33
33
  end
@@ -3,6 +3,31 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
3
3
  class MyViewContext
4
4
  include ActionView::Helpers::TagHelper
5
5
  include Stache::AssetHelper
6
+
7
+ def lookup_context
8
+ @context ||= LookupContext.new
9
+ end
10
+ end
11
+
12
+ class LookupContext
13
+ def find(name, prefixes = [], partial = false, keys = [], options = {})
14
+ raise ActionView::MissingTemplate.new(view_paths || [], name, prefixes, partial, options)
15
+ end
16
+
17
+ def view_paths= new_paths
18
+ @paths = ActionView::PathSet.new(Array.wrap(new_paths))
19
+ end
20
+
21
+ def view_paths
22
+ @paths
23
+ end
24
+ end
25
+
26
+ class TemplateStub
27
+ attr_accessor :source
28
+ def initialize source
29
+ self.source = source
30
+ end
6
31
  end
7
32
 
8
33
  describe Stache::AssetHelper do
@@ -12,54 +37,31 @@ describe Stache::AssetHelper do
12
37
 
13
38
  describe "#template_include_tag" do
14
39
  it "renders a script tag with the template contents" do
15
- File.stub!(:file?).with(Rails.root.join("app/views/widgets/_oh_herro.html.mustache").to_s).and_return(true)
16
- File.stub!(:open).with(Rails.root.join("app/views/widgets/_oh_herro.html.mustache"), "rb", {:encoding=>"utf-8"}).
17
- and_return(StringIO.new("{{ awyeah }}"))
40
+ helper.lookup_context.should_receive(:find).with('widgets/oh_herro', [], true, [], anything).and_return(TemplateStub.new("{{ awyeah }}"))
18
41
 
19
42
  helper.template_include_tag("widgets/oh_herro").should == "<script id=\"oh_herro_template\" type=\"text/html\">{{ awyeah }}</script>"
20
43
  end
21
- it "uses the template_base_path config setting to locate the template" do
22
- Stache.configure do |c|
23
- c.template_base_path = "/tmp/whee"
24
- end
25
- File.stub!(:file?).with("/tmp/whee/_whooo.html.mustache").and_return(true)
26
- File.stub!(:open).with(Pathname.new("/tmp/whee/_whooo.html.mustache"), "rb", {:encoding=>"utf-8"}).
27
- and_return(StringIO.new("{{ awyeah }}"))
44
+ it "renders a script tag with the template contents and given id" do
45
+ helper.lookup_context.should_receive(:find).with('widgets/oh_herro', [], true, [], anything).and_return(TemplateStub.new("{{ awyeah }}"))
28
46
 
29
- helper.template_include_tag("whooo").should == "<script id=\"whooo_template\" type=\"text/html\">{{ awyeah }}</script>"
47
+ helper.template_include_tag("widgets/oh_herro", :id => 'oh_herro_tmpl').should == "<script id=\"oh_herro_tmpl\" type=\"text/html\">{{ awyeah }}</script>"
30
48
  end
31
- it "raises if it cannot find the template" do
32
- lambda { helper.template_include_tag("arrrgh") }.should raise_error(ActionView::MissingTemplate)
33
- end
34
- end
49
+ it "renders a script tag with the template contents and given options" do
50
+ helper.lookup_context.should_receive(:find).with('widgets/oh_herro', [], true, [], anything).and_return(TemplateStub.new("{{ awyeah }}"))
35
51
 
36
- describe "#locate_template_for" do
37
- it "tries permutations of partial names and default file extension to find the requested file" do
38
- File.should_receive(:file?).with("/tmp/whee/_whooo.html.mustache")
39
- File.should_receive(:file?).with("/tmp/whee/whooo.html.mustache").and_return(true)
40
-
41
- helper.locate_template_for(Pathname.new("/tmp/whee"), "whooo").should == Pathname.new("/tmp/whee/whooo.html.mustache")
52
+ helper.template_include_tag("widgets/oh_herro", :data => {:engine => 'mustache'}).
53
+ should == "<script data-engine=\"mustache\" id=\"oh_herro_template\" type=\"text/html\">{{ awyeah }}</script>"
42
54
  end
55
+ it "will find first by partial and later by non-partial" do
56
+ helper.lookup_context.should_receive(:find).with('widgets/oh_herro', anything, true, anything, anything).and_raise(StandardError.new("noooooo"))
57
+ helper.lookup_context.should_receive(:find).with('widgets/oh_herro', anything, false, anything, anything).and_return(TemplateStub.new("{{ awyeah }}"))
43
58
 
44
- it "tries permutations of partial names and configured file extension to find the requested file" do
45
- Stache.configure do |config|
46
- @current_extension = config.template_extension
47
- config.template_extension = 'mustache'
48
- end
49
-
50
- File.should_receive(:file?).with("/tmp/whee/_whooo.mustache")
51
- File.should_receive(:file?).with("/tmp/whee/whooo.mustache").and_return(true)
52
-
53
- helper.locate_template_for(Pathname.new("/tmp/whee"), "whooo").should == Pathname.new("/tmp/whee/whooo.mustache")
54
-
55
- Stache.configure do |config|
56
- config.template_extension = @current_extension
57
- end
59
+ helper.template_include_tag("widgets/oh_herro").should == "<script id=\"oh_herro_template\" type=\"text/html\">{{ awyeah }}</script>"
58
60
  end
59
-
60
-
61
- it "returns nil if it cannot find anything" do
62
- helper.locate_template_for(Pathname.new("/tmp/whee"), "whooo").should be_nil
61
+ it "raises if it cannot find the template" do
62
+ lambda { helper.template_include_tag("arrrgh") }.should raise_error(ActionView::MissingTemplate)
63
63
  end
64
64
  end
65
+
66
+
65
67
  end
@@ -5,25 +5,23 @@ describe "Stache::Config" do
5
5
  before do
6
6
  Stache.send(:instance_variable_set, :@template_base_path, nil)
7
7
  end
8
- [:template_base_path, :template_extension, :shared_path].each do |attr|
8
+ [:template_base_path, :shared_path].each do |attr|
9
9
  it "sets up an attribute named #{attr.to_s}" do
10
10
  Stache.should respond_to(attr)
11
11
  Stache.should respond_to("#{attr}=")
12
12
  end
13
-
13
+
14
14
  it "sets up a default value for #{attr}" do
15
15
  Stache.send(attr).should_not be_nil
16
16
  Stache.send(attr).should == if attr == :template_base_path
17
17
  ::Rails.root.join('app', 'templates')
18
- elsif attr == :template_extension
19
- "html.mustache"
20
18
  elsif attr == :shared_path
21
19
  ::Rails.root.join('app', 'templates', 'shared')
22
20
  end
23
21
  end
24
22
  end
25
23
  end
26
-
24
+
27
25
  describe ".configure" do
28
26
  it "yields self to the block as a convienence to future refactoring" do
29
27
  Stache.configure do |config|
@@ -35,5 +33,5 @@ describe "Stache::Config" do
35
33
  end
36
34
  end
37
35
  end
38
-
36
+
39
37
  end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe Stache::Handlebars::Handler do
4
+ before do
5
+ @template = ActionView::Template.new("{{body}}", "hello handlebars", Stache::Handlebars::Handler, { :virtual_path => "hello_world"})
6
+ @handler = Stache::Handlebars::Handler.new
7
+ end
8
+
9
+ describe "#handlebars_class_from_template" do
10
+ it "returns the appropriate handlebars class" do
11
+ class HelloWorld < Stache::Handlebars::View; end
12
+ @handler.handlebars_class_from_template(@template).should == HelloWorld
13
+ Object.send(:remove_const, :HelloWorld)
14
+ end
15
+ it "is clever about folders and such" do
16
+ @template.stub!(:virtual_path).and_return("profiles/index")
17
+ module Profiles; class Index < Stache::Handlebars::View; end; end
18
+ @handler.handlebars_class_from_template(@template).should == Profiles::Index
19
+ Object.send(:remove_const, :Profiles)
20
+ end
21
+ it "retuns Stache::Handlebars::View if it can't find none" do
22
+ @handler.handlebars_class_from_template(@template).should == Stache::Handlebars::View
23
+ end
24
+ it "reraises error if loaded handlebars_class raises a NameError" do
25
+ @template.stub!(:virtual_path).and_return("profiles/index")
26
+ module Profiles; end
27
+ # Emulate autoload behavior so the error gets raised upon const_get
28
+ Profiles.autoload :Index, File.join(File.dirname(__FILE__), "profile_autoload.rb")
29
+
30
+ lambda {
31
+ @handler.handlebars_class_from_template(@template)
32
+ }.should raise_error(NameError, "uninitialized constant Profiles::Index::Foo")
33
+
34
+ Object.send(:remove_const, :Profiles)
35
+ end
36
+ end
37
+ end