erector-rails4 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/.coveralls.yml +1 -1
  3. data/.travis.yml +1 -1
  4. data/Appraisals +4 -1
  5. data/Guardfile +23 -0
  6. data/README.md +6 -1
  7. data/erector-rails4.gemspec +10 -3
  8. data/gemfiles/rails_3.gemfile +1 -0
  9. data/gemfiles/rails_4.0.gemfile +1 -0
  10. data/gemfiles/rails_4.1.gemfile +2 -1
  11. data/lib/erector-rails4.rb +1 -0
  12. data/lib/erector.rb +1 -4
  13. data/lib/erector/abstract_widget.rb +1 -12
  14. data/lib/erector/after_initialize.rb +7 -7
  15. data/lib/erector/caching.rb +35 -71
  16. data/lib/erector/element.rb +4 -4
  17. data/lib/erector/externals.rb +0 -8
  18. data/lib/erector/html_widget.rb +0 -11
  19. data/lib/erector/needs.rb +20 -9
  20. data/lib/erector/output.rb +2 -4
  21. data/lib/erector/promise.rb +4 -4
  22. data/lib/erector/rails.rb +6 -1
  23. data/lib/erector/rails/autoload_monkeypatch.rb +1 -1
  24. data/lib/erector/rails/railtie.rb +15 -8
  25. data/lib/erector/rails/template_handler.rb +2 -1
  26. data/lib/erector/text.rb +4 -8
  27. data/lib/erector/version.rb +1 -1
  28. data/lib/erector/widget.rb +2 -11
  29. data/lib/erector/xml_widget.rb +14 -18
  30. data/script/bootstrap +30 -0
  31. data/script/cibuild +3 -0
  32. data/script/performance +3 -0
  33. data/script/release +38 -0
  34. data/spec/dummy/app/views/test/_partial_with_rails_helpers.rb +7 -0
  35. data/spec/dummy/app/views/test/_user.rb +7 -0
  36. data/spec/dummy/app/views/test/_virtual_path_partial.rb +5 -0
  37. data/spec/dummy/app/views/test/erb_from_erector.html.rb +1 -1
  38. data/spec/dummy/app/views/test/erector_with_helpers_from_erb.html.erb +1 -0
  39. data/spec/dummy/app/views/test/{needs.html.rb → needs.rb} +0 -0
  40. data/spec/dummy/app/views/test/{needs_subclass.html.rb → needs_subclass.rb} +0 -0
  41. data/spec/dummy/app/views/test/render_partial.html.rb +1 -1
  42. data/spec/dummy/app/views/test/render_virtual_path.rb +7 -0
  43. data/spec/dummy/app/views/test/users.rb +9 -0
  44. data/spec/dummy/app/views/test_caching/_foos.rb +7 -0
  45. data/spec/dummy/app/views/test_caching/_partial.rb +9 -0
  46. data/spec/dummy/app/views/test_caching/cache_helper.rb +9 -0
  47. data/spec/dummy/app/views/test_caching/cache_helper_with_explicit_dependencies.rb +7 -0
  48. data/spec/dummy/app/views/test_caching/cache_helper_with_implicit_dependencies.rb +7 -0
  49. data/spec/dummy/app/views/test_caching/cache_helper_with_partial.rb +10 -0
  50. data/spec/dummy/app/views/test_caching/cache_helper_with_skip_digest.rb +9 -0
  51. data/spec/dummy/app/views/test_caching/cacheable_widget_with_dynamic_keys.rb +13 -0
  52. data/spec/dummy/app/views/test_caching/cacheable_widget_with_needs.rb +11 -0
  53. data/spec/dummy/app/views/test_caching/cacheable_widget_with_needs_keys.rb +11 -0
  54. data/spec/dummy/app/views/test_caching/cacheable_widget_with_skip_digest.rb +9 -0
  55. data/spec/dummy/app/views/test_caching/cacheable_widget_with_static_keys.rb +9 -0
  56. data/spec/dummy/config/application.rb +1 -1
  57. data/spec/dummy/spec/autoload_spec.rb +2 -2
  58. data/spec/dummy/spec/caching_spec.rb +180 -0
  59. data/spec/dummy/spec/form_builder_spec.rb +1 -1
  60. data/spec/dummy/spec/rails_helpers_spec.rb +21 -13
  61. data/spec/dummy/spec/rails_widget_spec.rb +1 -1
  62. data/spec/dummy/spec/render_spec.rb +23 -42
  63. data/spec/erector/dependency_spec.rb +0 -1
  64. data/spec/erector/html_spec.rb +4 -4
  65. data/spec/erector/indentation_spec.rb +2 -2
  66. data/spec/erector/needs_spec.rb +33 -0
  67. data/spec/erector/output_spec.rb +0 -2
  68. data/spec/erector/promise_spec.rb +2 -2
  69. data/spec/erector/widget_spec.rb +2 -2
  70. data/spec/performance/allocation_spec.rb +19 -0
  71. data/spec/performance/ruby_prof_spec.rb +23 -0
  72. data/spec/performance/widget_to_html_spec.rb +11 -5
  73. data/spec/spec_helper.rb +1 -10
  74. data/spec/support/capturing_output.rb +8 -0
  75. metadata +116 -17
  76. data/lib/erector/cache.rb +0 -41
  77. data/lib/erector/raw_string.rb +0 -12
  78. data/spec/dummy/spec/rails_spec_helper.rb +0 -10
  79. data/spec/erector/cache_spec.rb +0 -133
  80. data/spec/erector/caching_spec.rb +0 -202
@@ -28,9 +28,7 @@ module Erector
28
28
  end
29
29
 
30
30
  def <<(s)
31
- # raise s.inspect unless s.is_a? String
32
- #
33
- s = s.to_s unless s.is_a? String
31
+ s = s.to_s
34
32
  append_indentation
35
33
  if @max_length && s.length + @current_line_length > @max_length
36
34
  leading_spaces = s =~ /^( +)/ ? $1.size : 0
@@ -68,7 +66,7 @@ module Erector
68
66
  end
69
67
 
70
68
  def to_s
71
- RawString.new(buffer.kind_of?(String) ? buffer : buffer.join)
69
+ (buffer.kind_of?(String) ? buffer : buffer.join).html_safe
72
70
  end
73
71
 
74
72
  def to_a
@@ -52,12 +52,12 @@ module Erector
52
52
 
53
53
  @output.newline if !@self_closing and @newliney and !@output.at_line_start?
54
54
 
55
- @output << RawString.new( "<#{@tag_name}#{Promise.format_attributes(@attributes)}")
55
+ @output << "<#{@tag_name}#{Promise.format_attributes(@attributes)}".html_safe
56
56
  if @self_closing
57
- @output << RawString.new( " />")
57
+ @output << " />".html_safe
58
58
  @output.newline if @newliney
59
59
  else
60
- @output << RawString.new( ">")
60
+ @output << ">".html_safe
61
61
  @output.indent
62
62
  end
63
63
  end
@@ -76,7 +76,7 @@ module Erector
76
76
  return if @self_closing
77
77
 
78
78
  @output.undent
79
- @output<< RawString.new("</#{@tag_name}>")
79
+ @output << "</#{@tag_name}>".html_safe
80
80
  if @newliney
81
81
  @output.newline
82
82
  end
@@ -36,12 +36,17 @@ module Erector
36
36
  widget_class_variable_name = $1 if widget_class_variable_name =~ %r{.*/(.*?)$}
37
37
 
38
38
  local_assigns.reject do |name, value|
39
- name == :object || name == widget_class_variable_name.to_sym
39
+ name == :object || (name == widget_class_variable_name.to_sym && value.nil?)
40
40
  end
41
41
  end
42
42
 
43
43
  def render(widget, view, local_assigns = {}, is_partial = false, options = {})
44
44
  widget = widget.new(assigns_for(widget, view, local_assigns, is_partial)) if widget.is_a?(Class)
45
+
46
+ if options[:pathname]
47
+ widget.instance_variable_set(:@virtual_path, options[:pathname])
48
+ end
49
+
45
50
  view.with_output_buffer do
46
51
  # Set parent and helpers to the view and use Rails's output buffer.
47
52
  widget.to_html(options.merge(:helpers => view,
@@ -1,7 +1,7 @@
1
1
  module ActiveSupport
2
2
  module Dependencies
3
3
 
4
- def search_for_file(path_suffix)
4
+ def self.search_for_file(path_suffix)
5
5
  path_suffix = path_suffix.sub(/(\.rb)?$/, ".rb")
6
6
  underscored_path_suffix = path_suffix.gsub(/\/([\w\.]*$)/, '/_\1')
7
7
 
@@ -1,13 +1,20 @@
1
1
  module Erector
2
2
  class Railtie < ::Rails::Railtie
3
- # config.generators.template_engine :rb
3
+ initializer 'erector.autoload', before: :set_autoload_paths do |app|
4
+ app.config.autoload_paths << "#{::Rails.root}/app"
5
+ end
4
6
 
5
- # TODO: automatically add app directory to app.config.autoload_paths,
6
- # so that Views::Foo::Bar autoloads, and 'require "views/foo/bar.html"'
7
- # works. For now, you must add the following to config/application.rb:
8
- #
9
- # config.autoload_paths += %W(#{config.root}/app)
10
- #
11
- # (Maybe ::Rails.configuration.autoload_paths will work?)
7
+ initializer 'erector.dependency_tracker' do
8
+ ActiveSupport.on_load(:action_view) do
9
+ ActiveSupport.on_load(:after_initialize) do
10
+ begin
11
+ require 'action_view/dependency_tracker'
12
+ ActionView::DependencyTracker.register_tracker :rb, ActionView::DependencyTracker::ERBTracker
13
+ rescue LoadError
14
+ # likely this version of Rails doesn't support dependency tracking
15
+ end
16
+ end
17
+ end
18
+ end
12
19
  end
13
20
  end
@@ -3,10 +3,11 @@ module Erector
3
3
  class TemplateHandler
4
4
  def call(template)
5
5
  require_dependency template.identifier
6
+ pathname = "#{template.identifier =~ %r(views/(.*)) && $1}"
6
7
  widget_class_name = "views/#{template.identifier =~ %r(views/([^.]*)(\..*)?\.rb) && $1}".camelize
7
8
  is_partial = File.basename(template.identifier) =~ /^_/
8
9
  <<-SRC
9
- Erector::Rails.render(#{widget_class_name}, self, local_assigns, #{!!is_partial})
10
+ Erector::Rails.render(#{widget_class_name}, self, local_assigns, #{!!is_partial}, pathname: "#{pathname}")
10
11
  SRC
11
12
  end
12
13
  end
@@ -1,5 +1,3 @@
1
- require "erector/raw_string"
2
-
3
1
  module Erector
4
2
  module Text
5
3
  # Emits text to the output buffer, e.g.
@@ -20,7 +18,7 @@ module Erector
20
18
  # will be emitted to the output stream in turn. You can specify a delimiter
21
19
  # by using an options hash with as the final argument, using +:join+ as the key,
22
20
  # e.g.
23
- #
21
+ #
24
22
  # text "my", "dog", "smells", :join => " "
25
23
  # => "my dog smells"
26
24
  #
@@ -73,16 +71,14 @@ module Erector
73
71
 
74
72
  # Returns text which will *not* be HTML-escaped.
75
73
  def raw(value)
76
- RawString.new(value.to_s)
74
+ value.html_safe if value
77
75
  end
78
76
 
79
77
  # Emits text which will *not* be HTML-escaped. Same effect as text(raw(s))
80
- def text!(value)
78
+ def rawtext(value)
81
79
  text raw(value)
82
80
  end
83
81
 
84
- alias rawtext text!
85
-
86
82
  # Returns a copy of value with spaces replaced by non-breaking space characters.
87
83
  # With no arguments, return a single non-breaking space.
88
84
  # The output uses the escaping format '&#160;' since that works
@@ -99,7 +95,7 @@ module Erector
99
95
  if content.respond_to?(:html_safe?) && content.html_safe?
100
96
  content
101
97
  else
102
- raw(CGI.escapeHTML(content.to_s))
98
+ raw(CGI::escapeHTML(content.to_s))
103
99
  end
104
100
  end
105
101
 
@@ -1,3 +1,3 @@
1
1
  module Erector
2
- VERSION = "0.1.3"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -5,6 +5,7 @@ require "erector/text"
5
5
  require "erector/tag"
6
6
  require "erector/html_widget"
7
7
  require "erector/needs"
8
+ require "erector/caching"
8
9
 
9
10
  module Erector
10
11
 
@@ -51,7 +52,6 @@ module Erector
51
52
  # * Attributes
52
53
  # * Text
53
54
  # * Needs
54
- # * Caching
55
55
  # * Externals
56
56
  # * AfterInitialize
57
57
  #
@@ -71,6 +71,7 @@ module Erector
71
71
 
72
72
  include HTML
73
73
  include Convenience
74
+ include Caching
74
75
  include Erector::JQuery
75
76
  include Erector::Sass if Object.const_defined?(:Sass)
76
77
 
@@ -80,15 +81,5 @@ module Erector
80
81
  _emit(options).to_s
81
82
  end
82
83
 
83
- # alias for #to_html
84
- # @deprecated Please use {#to_html} instead
85
- def to_s(*args)
86
- unless defined? @@already_warned_to_s
87
- $stderr.puts "Erector::Widget#to_s is deprecated. Please use #to_html instead. Called from #{caller.first}"
88
- @@already_warned_to_s = true
89
- end
90
- to_html(*args)
91
- end
92
-
93
84
  end
94
85
  end
@@ -9,24 +9,21 @@ module Erector
9
9
  class XMLWidget < AbstractWidget
10
10
  include Needs
11
11
 
12
- def self.tag_named tag_name, checked = []
12
+ def self.inherited(subclass)
13
+ super
14
+ subclass.add_tags(@tags) if @tags
15
+ end
16
+
17
+ def self.tag_named(tag_name)
18
+ @tags && @tags[tag_name]
19
+ end
20
+
21
+ def self.add_tags(tags)
13
22
  @tags ||= {}
14
- @tags[tag_name] || begin
15
- tag = nil
16
- checked << self
17
- taggy_ancestors = (ancestors - checked).select{|k| k.respond_to? :tag_named}
18
- taggy_ancestors.each do |k|
19
- tag = k.tag_named(tag_name, checked)
20
- if tag
21
- @tags[tag_name] = tag
22
- break
23
- end
24
- end
25
- tag
26
- end
23
+ @tags = @tags.merge(tags)
27
24
  end
28
25
 
29
- def self.tag *args
26
+ def self.tag(*args)
30
27
  tag = Tag.new(*args)
31
28
  @tags ||= {}
32
29
  @tags[tag.name] = tag
@@ -65,9 +62,8 @@ module Erector
65
62
  @tags.values.select{|tag| !tag.self_closing?}.map{|tag| tag.name}
66
63
  end
67
64
 
68
- def newliney?(tag_name)
69
- tag = self.class.tag_named tag_name
70
- if tag
65
+ def self.newliney?(tag_name)
66
+ if (tag = self.tag_named(tag_name))
71
67
  tag.newliney?
72
68
  else
73
69
  true
@@ -0,0 +1,30 @@
1
+ #! /bin/bash
2
+
3
+ ## Make sure we're in the project root
4
+ cd $(dirname "$0")/..
5
+
6
+ ## Check dependencies
7
+ printf "Checking dependencies... "
8
+
9
+ deps=(
10
+ ruby
11
+ bundler
12
+ git
13
+ )
14
+
15
+ for i in "${deps[@]}"
16
+ do
17
+ :
18
+ if [ ! $(which $i) ]; then
19
+ printf "\nDependency check failed, file not in PATH: $i\n"
20
+ exit 1
21
+ fi
22
+ done
23
+
24
+ printf "OK\n"
25
+
26
+ ## Bundle
27
+ printf "Bundling...\n"
28
+ bundle install
29
+
30
+ printf "\nSuccess!\n\n"
@@ -0,0 +1,3 @@
1
+ #!/bin/sh
2
+
3
+ bundle exec rspec
@@ -0,0 +1,3 @@
1
+ #!/bin/sh
2
+
3
+ bundle exec rspec -t performance
@@ -0,0 +1,38 @@
1
+ #!/bin/sh
2
+ # Tag and push a release.
3
+
4
+ set -e
5
+
6
+ # Make sure we're in the project root.
7
+
8
+ cd $(dirname "$0")/..
9
+
10
+ # Build a new gem archive.
11
+
12
+ rm -rf erector-rails4-*.gem
13
+ gem build -q erector-rails4.gemspec
14
+
15
+ # Make sure we're on the master branch.
16
+
17
+ (git branch | grep -q '* master') || {
18
+ echo "Only release from the master branch."
19
+ exit 1
20
+ }
21
+
22
+ # Figure out what version we're releasing.
23
+
24
+ tag=v`ls erector-rails4-*.gem | sed 's/^erector-rails4-\(.*\)\.gem$/\1/'`
25
+
26
+ # Make sure we haven't released this version before.
27
+
28
+ git fetch -t origin
29
+
30
+ (git tag -l | grep -q "$tag") && {
31
+ echo "Whoops, there's already a '${tag}' tag."
32
+ exit 1
33
+ }
34
+
35
+ # Tag it and bag it.
36
+
37
+ gem push erector-rails4-*.gem && git tag "$tag" &&
38
+ git push origin master && git push origin "$tag"
@@ -0,0 +1,7 @@
1
+ class Views::Test::PartialWithRailsHelpers < Erector::Widget
2
+ def content
3
+ form_tag 'foobar' do
4
+ submit_tag
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ class Views::Test::User < Erector::Widget
2
+ needs :user
3
+
4
+ def content
5
+ text @user
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ class Views::Test::VirtualPathPartial < Erector::Widget
2
+ def content
3
+ text @virtual_path
4
+ end
5
+ end
@@ -1,5 +1,5 @@
1
1
  class Views::Test::ErbFromErector < Erector::Widget
2
2
  def content
3
- text! parent.render(:partial => 'erb')
3
+ rawtext parent.render(:partial => 'erb')
4
4
  end
5
5
  end
@@ -0,0 +1 @@
1
+ <%= render :partial => 'partial_with_rails_helpers' %>
@@ -1,5 +1,5 @@
1
1
  class Views::Test::RenderPartial < Erector::Widget
2
2
  def content
3
- text! parent.render(:partial => 'erector')
3
+ rawtext parent.render(:partial => 'erector')
4
4
  end
5
5
  end
@@ -0,0 +1,7 @@
1
+ class Views::Test::RenderVirtualPath < Erector::Widget
2
+ def content
3
+ text @virtual_path
4
+ text ','
5
+ render 'virtual_path_partial'
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ class Views::Test::Users < Erector::Widget
2
+
3
+ def content
4
+ ["Foo", "Bar"].each do |x|
5
+ render 'user', user: x
6
+ end
7
+ end
8
+
9
+ end
@@ -0,0 +1,7 @@
1
+ class Views::TestCaching::Foos < Erector::Widget
2
+
3
+ def content
4
+ text 'foos'
5
+ end
6
+
7
+ end
@@ -0,0 +1,9 @@
1
+ class Views::TestCaching::Partial < Erector::Widget
2
+
3
+ def content
4
+ cache 'partial_key' do
5
+ text DateTime.current
6
+ end
7
+ end
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ class Views::TestCaching::CacheHelper < Erector::Widget
2
+
3
+ def content
4
+ cache 'cache_helper_key' do
5
+ text DateTime.current
6
+ end
7
+ end
8
+
9
+ end
@@ -0,0 +1,7 @@
1
+ class Views::TestCaching::CacheHelperWithExplicitDependencies < Erector::Widget
2
+
3
+ def content
4
+ # Template Dependency: test_caching/foos
5
+ end
6
+
7
+ end
@@ -0,0 +1,7 @@
1
+ class Views::TestCaching::CacheHelperWithImplicitDependencies < Erector::Widget
2
+
3
+ def content
4
+ render 'foos'
5
+ end
6
+
7
+ end