erector-rails4 0.1.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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