garterbelt 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,6 +1,5 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- gem 'ru_pol', '0.1.2'
4
3
  gem 'activesupport', ">=2.3.8"
5
4
  gem 'moneta', '>=0.6.0'
6
5
 
data/Gemfile.lock CHANGED
@@ -20,7 +20,6 @@ GEM
20
20
  rspec-expectations (2.3.0)
21
21
  diff-lcs (~> 1.1.2)
22
22
  rspec-mocks (2.3.0)
23
- ru_pol (0.1.2)
24
23
  yard (0.6.5)
25
24
 
26
25
  PLATFORMS
@@ -34,5 +33,4 @@ DEPENDENCIES
34
33
  moneta (>= 0.6.0)
35
34
  rcov
36
35
  rspec (~> 2.3.0)
37
- ru_pol (= 0.1.2)
38
36
  yard (~> 0.6.0)
data/Rakefile CHANGED
@@ -23,7 +23,6 @@ Jeweler::Tasks.new do |gem|
23
23
  gem.add_development_dependency 'hashie', '~>1.0'
24
24
  gem.add_development_dependency 'rbench'
25
25
 
26
- gem.add_runtime_dependency 'ru_pol', '>=0.1.2'
27
26
  gem.add_runtime_dependency 'activesupport', '>=2.3.8'
28
27
  gem.add_runtime_dependency 'moneta', '>=0.6.0'
29
28
  end
data/TODO CHANGED
@@ -1,6 +1,5 @@
1
- Page
2
-
3
- - partial passes down params from parent view
4
- - partial receives a block
1
+ increase performance ~10%
2
+ partial passes down params from parent view
3
+ anonymous view
5
4
 
6
5
  Rails Helpers
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.4
1
+ 0.0.5
data/garterbelt.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{garterbelt}
8
- s.version = "0.0.4"
8
+ s.version = "0.0.5"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Kane Baccigalupi"]
12
- s.date = %q{2011-04-12}
12
+ s.date = %q{2011-04-13}
13
13
  s.description = %q{Garterbelt is a Ruby HTML/XML markup framework inspired by Erector and Markaby. Garterbelt maps html tags to methods allowing the intuitive construction of HTML pages using nothing but Ruby. And because it is all Ruby all the time, views benefit from the dryness of inheritance, modules and all the meta magic that Ruby can imagine. Stockings not included.}
14
14
  s.email = %q{baccigalupi@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -42,23 +42,27 @@ Gem::Specification.new do |s|
42
42
  "lib/stocking.rb",
43
43
  "lib/support/string.rb",
44
44
  "lib/view.rb",
45
- "spec/benchmark/templates/erector.rb",
46
- "spec/benchmark/templates/garterbelt.rb",
47
- "spec/benchmark/vs_erector.rb",
48
45
  "spec/garterbelt_spec.rb",
49
46
  "spec/integration/expectations/general_view.html",
50
47
  "spec/integration/expectations/variables/view_with_user_and_params.html",
51
48
  "spec/integration/expectations/variables/view_with_user_email.html",
52
49
  "spec/integration/expectations/view_partial_nest.html",
50
+ "spec/integration/expectations/view_with_forms.html",
53
51
  "spec/integration/expectations/view_with_tags.html",
52
+ "spec/integration/templates/form.rb",
54
53
  "spec/integration/templates/view_partial_nest.rb",
55
54
  "spec/integration/templates/view_with_cache.rb",
55
+ "spec/integration/templates/view_with_forms.rb",
56
56
  "spec/integration/templates/view_with_partial.rb",
57
57
  "spec/integration/templates/view_with_partial_2.rb",
58
58
  "spec/integration/templates/view_with_tags.rb",
59
59
  "spec/integration/templates/view_with_vars.rb",
60
60
  "spec/integration/view_spec.rb",
61
61
  "spec/page_spec.rb",
62
+ "spec/performance/profiling.rb",
63
+ "spec/performance/templates/erector.rb",
64
+ "spec/performance/templates/garterbelt.rb",
65
+ "spec/performance/vs_erector.rb",
62
66
  "spec/renderers/cache_spec.rb",
63
67
  "spec/renderers/closed_tag_spec.rb",
64
68
  "spec/renderers/comment_spec.rb",
@@ -81,18 +85,21 @@ Gem::Specification.new do |s|
81
85
  s.rubygems_version = %q{1.3.7}
82
86
  s.summary = %q{Garterbelt is a Ruby HTML/XML markup framework. It is san DSL. Just all Ruby, all the time.}
83
87
  s.test_files = [
84
- "spec/benchmark/templates/erector.rb",
85
- "spec/benchmark/templates/garterbelt.rb",
86
- "spec/benchmark/vs_erector.rb",
87
88
  "spec/garterbelt_spec.rb",
89
+ "spec/integration/templates/form.rb",
88
90
  "spec/integration/templates/view_partial_nest.rb",
89
91
  "spec/integration/templates/view_with_cache.rb",
92
+ "spec/integration/templates/view_with_forms.rb",
90
93
  "spec/integration/templates/view_with_partial.rb",
91
94
  "spec/integration/templates/view_with_partial_2.rb",
92
95
  "spec/integration/templates/view_with_tags.rb",
93
96
  "spec/integration/templates/view_with_vars.rb",
94
97
  "spec/integration/view_spec.rb",
95
98
  "spec/page_spec.rb",
99
+ "spec/performance/profiling.rb",
100
+ "spec/performance/templates/erector.rb",
101
+ "spec/performance/templates/garterbelt.rb",
102
+ "spec/performance/vs_erector.rb",
96
103
  "spec/renderers/cache_spec.rb",
97
104
  "spec/renderers/closed_tag_spec.rb",
98
105
  "spec/renderers/comment_spec.rb",
@@ -115,7 +122,6 @@ Gem::Specification.new do |s|
115
122
  s.specification_version = 3
116
123
 
117
124
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
118
- s.add_runtime_dependency(%q<ru_pol>, ["= 0.1.2"])
119
125
  s.add_runtime_dependency(%q<activesupport>, [">= 2.3.8"])
120
126
  s.add_runtime_dependency(%q<moneta>, [">= 0.6.0"])
121
127
  s.add_development_dependency(%q<hashie>, ["~> 1.0"])
@@ -126,11 +132,9 @@ Gem::Specification.new do |s|
126
132
  s.add_development_dependency(%q<rcov>, [">= 0"])
127
133
  s.add_development_dependency(%q<hashie>, ["~> 1.0"])
128
134
  s.add_development_dependency(%q<rbench>, [">= 0"])
129
- s.add_runtime_dependency(%q<ru_pol>, [">= 0.1.2"])
130
135
  s.add_runtime_dependency(%q<activesupport>, [">= 2.3.8"])
131
136
  s.add_runtime_dependency(%q<moneta>, [">= 0.6.0"])
132
137
  else
133
- s.add_dependency(%q<ru_pol>, ["= 0.1.2"])
134
138
  s.add_dependency(%q<activesupport>, [">= 2.3.8"])
135
139
  s.add_dependency(%q<moneta>, [">= 0.6.0"])
136
140
  s.add_dependency(%q<hashie>, ["~> 1.0"])
@@ -141,12 +145,10 @@ Gem::Specification.new do |s|
141
145
  s.add_dependency(%q<rcov>, [">= 0"])
142
146
  s.add_dependency(%q<hashie>, ["~> 1.0"])
143
147
  s.add_dependency(%q<rbench>, [">= 0"])
144
- s.add_dependency(%q<ru_pol>, [">= 0.1.2"])
145
148
  s.add_dependency(%q<activesupport>, [">= 2.3.8"])
146
149
  s.add_dependency(%q<moneta>, [">= 0.6.0"])
147
150
  end
148
151
  else
149
- s.add_dependency(%q<ru_pol>, ["= 0.1.2"])
150
152
  s.add_dependency(%q<activesupport>, [">= 2.3.8"])
151
153
  s.add_dependency(%q<moneta>, [">= 0.6.0"])
152
154
  s.add_dependency(%q<hashie>, ["~> 1.0"])
@@ -157,7 +159,6 @@ Gem::Specification.new do |s|
157
159
  s.add_dependency(%q<rcov>, [">= 0"])
158
160
  s.add_dependency(%q<hashie>, ["~> 1.0"])
159
161
  s.add_dependency(%q<rbench>, [">= 0"])
160
- s.add_dependency(%q<ru_pol>, [">= 0.1.2"])
161
162
  s.add_dependency(%q<activesupport>, [">= 2.3.8"])
162
163
  s.add_dependency(%q<moneta>, [">= 0.6.0"])
163
164
  end
data/lib/garterbelt.rb CHANGED
@@ -3,7 +3,6 @@ stocking_dir = File.dirname(__FILE__)
3
3
  require 'active_support/core_ext/string/output_safety'
4
4
  require stocking_dir + '/support/string'
5
5
 
6
- require 'ru_pol'
7
6
  require 'moneta'
8
7
  require 'moneta/memory'
9
8
 
@@ -1,8 +1,5 @@
1
1
  module Garterbelt
2
2
  class ClosedTag < Renderer
3
- include RuPol::Swimsuit
4
- max_pool_size 10000
5
-
6
3
  attr_accessor :type, :attributes, :css_class
7
4
 
8
5
  def initialize(opts)
@@ -1,7 +1,5 @@
1
1
  module Garterbelt
2
2
  class Comment < Text
3
- max_pool_size 1000
4
-
5
3
  def initialize(opts)
6
4
  super
7
5
  end
@@ -1,7 +1,5 @@
1
1
  module Garterbelt
2
2
  class Doctype < ClosedTag
3
- max_pool_size 1000
4
-
5
3
  ATTRIBUTES = {
6
4
  :transitional => "html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"",
7
5
  :strict => 'html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"',
@@ -1,8 +1,5 @@
1
1
  module Garterbelt
2
2
  class Renderer
3
- include RuPol::Swimsuit
4
- max_pool_size 10000
5
-
6
3
  attr_accessor :view
7
4
 
8
5
  def initialize(opts)
data/lib/renderers/xml.rb CHANGED
@@ -1,7 +1,5 @@
1
1
  module Garterbelt
2
2
  class Xml < ClosedTag
3
- max_pool_size 1000
4
-
5
3
  def template
6
4
  "#{indent}<?xml #{rendered_attributes} ?>\n"
7
5
  end
data/lib/view.rb CHANGED
@@ -1,17 +1,19 @@
1
1
  module Garterbelt
2
2
  class View
3
- include RuPol::Swimsuit
3
+ # include RuPol::Swimsuit
4
4
 
5
- attr_accessor :output, :buffer, :level, :escape
5
+ attr_accessor :output, :buffer, :level, :escape, :block, :options
6
6
  attr_reader :curator
7
7
 
8
- def initialize(opts={})
8
+ def initialize(opts={}, &block)
9
+ self.options = opts
9
10
  self.buffer = []
10
- self.level = (opts.delete(:level) || 0)
11
+ self.level = (options.delete(:level) || 0)
11
12
  self.output = ""
12
13
  self.escape = true
14
+ self.block = block if block_given?
13
15
 
14
- self.curator = opts.delete(:curator) || self
16
+ self.curator = options.delete(:curator) || self
15
17
 
16
18
  params = self.class.default_variables.merge(opts)
17
19
  keys = params.keys
@@ -25,8 +27,8 @@ module Garterbelt
25
27
  end
26
28
 
27
29
  params.each do |key, value|
28
- self.class.add_accssor(key) unless respond_to?(key)
29
- send("#{key}=", value)
30
+ self.class.add_accessor(key) unless respond_to?(key)
31
+ instance_variable_set "@#{key}", value
30
32
  end
31
33
  end
32
34
 
@@ -49,10 +51,10 @@ module Garterbelt
49
51
  attr_accessor :required, :selective_require
50
52
  end
51
53
 
52
- def self.add_accssor key
54
+ def self.add_accessor key
53
55
  key = key.to_s
54
56
  return if accessories.include?(key)
55
- if instance_methods.include?(key)
57
+ if (instance_methods - Object.instance_methods).include?(key)
56
58
  raise ArgumentError, ":#{key} cannot be a required variable because it maps to an existing method"
57
59
  end
58
60
 
@@ -100,7 +102,7 @@ module Garterbelt
100
102
 
101
103
  def self.build_accessors
102
104
  required.each do |m|
103
- add_accssor m
105
+ add_accessor m
104
106
  end
105
107
  end
106
108
 
@@ -112,7 +114,12 @@ module Garterbelt
112
114
  end
113
115
 
114
116
  def tag(type, *args, &block)
115
- add_to_buffer ContentTag.new(parse_tag_arguments(type, args), &block)
117
+ t = if block_given?
118
+ ContentTag.new(parse_tag_arguments(type, args), &block)
119
+ else
120
+ ContentTag.new(parse_tag_arguments(type, args))
121
+ end
122
+ add_to_buffer t
116
123
  end
117
124
 
118
125
  def closed_tag(type, *args)
@@ -122,11 +129,11 @@ module Garterbelt
122
129
  def non_escape_tag(*args, &block)
123
130
  if escape
124
131
  curator.escape = false
125
- t = tag(*args, &block)
132
+ t = block_given? ? tag(*args, &block) : tag(*args)
126
133
  curator.escape = true
127
134
  t
128
135
  else
129
- tag(*args, &block)
136
+ block_given? ? tag(*args, &block) : tag(*args)
130
137
  end
131
138
  end
132
139
 
@@ -149,7 +156,7 @@ module Garterbelt
149
156
  alias :raw :raw_text
150
157
  alias :rawtext :raw_text
151
158
 
152
- def comment(content)
159
+ def comment_tag(content)
153
160
  add_to_buffer Comment.new(:view => curator, :content => content)
154
161
  end
155
162
 
@@ -197,7 +204,7 @@ module Garterbelt
197
204
  CONTENT_TAGS.each do |type|
198
205
  class_eval <<-RUBY
199
206
  def #{type}(*args, &block)
200
- tag(:#{type}, *args, &block)
207
+ block_given? ? tag(:#{type}, *args, &block) : tag(:#{type}, *args)
201
208
  end
202
209
  RUBY
203
210
  end
@@ -206,7 +213,7 @@ module Garterbelt
206
213
  NON_ESCAPE_TAGS.each do |type|
207
214
  class_eval <<-RUBY
208
215
  def #{type}(*args, &block)
209
- non_escape_tag(:#{type}, *args, &block)
216
+ block_given? ? non_escape_tag(:#{type}, *args, &block) : non_escape_tag(:#{type}, *args)
210
217
  end
211
218
  RUBY
212
219
  end
@@ -230,7 +237,7 @@ module Garterbelt
230
237
  end
231
238
 
232
239
  def page_title(*args, &block)
233
- tag(:title, *args, &block)
240
+ block_given? ? tag(:title, *args, &block) : tag(:title, *args)
234
241
  end
235
242
 
236
243
  def stylesheet_link(path)
@@ -258,6 +265,13 @@ module Garterbelt
258
265
  output
259
266
  end
260
267
 
268
+ def render_block
269
+ return output unless block
270
+ block.call
271
+ render_buffer
272
+ output
273
+ end
274
+
261
275
  alias :to_s :render
262
276
  alias :to_html :render
263
277
 
@@ -267,25 +281,27 @@ module Garterbelt
267
281
  array.each do |item|
268
282
  if item.respond_to?(:render)
269
283
  item.render
270
- item.recycle
271
284
  else
272
285
  output << item.to_s
273
286
  end
274
287
  end
275
288
  end
276
289
 
277
- def self.render(opts={})
278
- content_method = opts[:method]
279
- view = new
290
+ def self.render(opts={}, &block)
291
+ content_method = opts.delete(:method)
292
+ view = block_given? ? new(opts, &block) : new(opts)
280
293
  output = content_method ? view.render(content_method) : view.render
281
- view.recycle
282
294
  output
283
295
  end
284
296
 
285
297
  def partial(*args, &block)
286
298
  if (klass = args.first).is_a?(Class)
287
299
  args.shift
288
- view = klass.new(*args)
300
+ view = if block
301
+ klass.new(*args, &block)
302
+ else
303
+ klass.new(*args)
304
+ end
289
305
  else
290
306
  view = args.first
291
307
  end
@@ -16,20 +16,6 @@ describe Garterbelt do
16
16
  end
17
17
  end
18
18
 
19
- describe '#cache=' do
20
- it 'creates a Moneta cache' do
21
-
22
- end
23
-
24
- describe 'options' do
25
- it 'creates a memory Moneta cache correctly'
26
- it 'creates a file system Moneta cache'
27
- it 'creates alternative types as requested'
28
- end
29
- it 'sets the default key when not provided a argument'
30
- it 'sets other keys when not '
31
- end
32
-
33
19
  describe '#cache' do
34
20
  it 'returns the :default if no arugment is received' do
35
21
  Garterbelt.cache.should == Garterbelt.cache_hash[:default]
@@ -0,0 +1,29 @@
1
+ <div class="servey">
2
+ <form action="/form/fu" method="get">
3
+ <label>
4
+ <h4>
5
+ Are you fu?
6
+ </h4>
7
+ <input name="fu" type="radio" value="yes">
8
+ Yes!
9
+ <input name="fu" type="radio" value="no">
10
+ no :(
11
+ </label>
12
+ <input type="submit" value="Answer the Fu Master">
13
+ </form>
14
+ <form class="update" action="/user/info" method="post">
15
+ <input name="_method" type="hidden" value="put">
16
+ <h4>
17
+ Provide us with updated information
18
+ </h4>
19
+ <label>
20
+ Name:
21
+ <input name="name" type="text">
22
+ </label>
23
+ <label>
24
+ Email:
25
+ <input name="email" type="text">
26
+ </label>
27
+ <input type="submit" value="Update">
28
+ </form>
29
+ </div>
@@ -0,0 +1,30 @@
1
+ class FormView < Garterbelt::View
2
+ requires :method => :get
3
+
4
+ def initialize(options, &block)
5
+ super
6
+ self.method = method.to_s.downcase
7
+ end
8
+
9
+ def content
10
+ form form_options do
11
+ if legal_method != method
12
+ input :type => 'hidden', :name => "_method", :value => method
13
+ end
14
+
15
+ block.call if block
16
+ end
17
+ end
18
+
19
+ def form_options
20
+ options.merge(:method => legal_method)
21
+ end
22
+
23
+ def legal_method
24
+ if ['get', 'post'].include?( method )
25
+ method
26
+ else
27
+ 'post'
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,31 @@
1
+ class ViewWithForms < Garterbelt::View
2
+ def content
3
+ div :class => 'servey' do
4
+ partial FormView, :action => '/form/fu' do
5
+ label do
6
+ h4 "Are you fu?"
7
+ input :type => 'radio', :name => 'fu', :value => 'yes'
8
+ text 'Yes!'
9
+ input :type => 'radio', :name => 'fu', :value => 'no'
10
+ text 'no :('
11
+ end
12
+
13
+ input :type => 'submit', :value => "Answer the Fu Master"
14
+ end
15
+
16
+ partial FormView, :action => '/user/info', :method => 'put', :class => 'update' do
17
+ h4 "Provide us with updated information"
18
+ label do
19
+ text "Name: "
20
+ input :type => 'text', :name => 'name'
21
+ end
22
+
23
+ label do
24
+ text "Email: "
25
+ input :type => 'text', :name => 'email'
26
+ end
27
+ input :type => 'submit', :value => 'Update'
28
+ end
29
+ end
30
+ end
31
+ end
@@ -53,5 +53,9 @@ describe Garterbelt::View, "Integration" do
53
53
  it 'nests deeply' do
54
54
  MyPagelet.new(:user => @user).render.should == file('view_partial_nest')
55
55
  end
56
+
57
+ it 'works with passed blocks' do
58
+ ViewWithForms.new.render.should == file('view_with_forms')
59
+ end
56
60
  end
57
61
  end
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require "rbench"
5
+ require 'hashie'
6
+
7
+ require File.dirname(__FILE__) + "/../../lib/garterbelt"
8
+ require File.dirname(__FILE__) + '/templates/garterbelt'
9
+
10
+ TIMES = 10_000
11
+
12
+ require 'ruby-prof'
13
+
14
+ # Profile the code
15
+ @view = Garterbelt::View.new
16
+ @tag = Garterbelt::ContentTag.new(:type => :p, :view => @view) do
17
+ @view.buffer << Garterbelt::ContentTag.new(:type => :span, :view => @view, :content => 'spanning')
18
+ @view.buffer << Garterbelt::Text.new(:content => ' so much time here', :view => @view)
19
+ end
20
+
21
+ result = RubyProf.profile do
22
+ TIMES.times do
23
+ @tag.render
24
+ end
25
+ end
26
+
27
+ # Print a graph profile to text
28
+ printer = RubyProf::GraphPrinter.new(result)
29
+ printer.print(STDOUT, 0)
@@ -11,21 +11,21 @@ class ErectorTemplate < Erector::Widget
11
11
 
12
12
  body :class => self.class.to_s.underscore do
13
13
  div :id => :wrapper, :class => 'line' do
14
- if flash
14
+ if @flash
15
15
  div :id => 'flash', :class => 'inner' do
16
- text flash
16
+ text @flash
17
17
  end
18
18
  end
19
19
 
20
- dl :class => ['inner', 'user_info'] do
21
- dt 'username'
22
- dd user.username
20
+ dl :class => ['inner', '@user_info'] do
21
+ dt '@username'
22
+ dd @user.username
23
23
 
24
24
  dt 'email'
25
- dd user.email
25
+ dd @user.email
26
26
 
27
27
  dt 'name'
28
- dd user.name
28
+ dd @user.name
29
29
 
30
30
  dt 'number of assigned tasks'
31
31
  dd rand(20)
@@ -4,9 +4,9 @@ class GarterbeltTemplate < Garterbelt::View
4
4
  def content
5
5
  html do
6
6
  head do
7
- title "Benchmarking Templates"
8
- link :rel => 'stylesheet', :href => '/stylesheet/application.css'
9
- link :rel => 'stylesheet', :href => '/stylesheet/ie.css'
7
+ page_title "Benchmarking Templates"
8
+ _link :rel => 'stylesheet', :href => '/stylesheet/application.css'
9
+ _link :rel => 'stylesheet', :href => '/stylesheet/ie.css'
10
10
  end
11
11
 
12
12
  body :class => self.class.to_s.underscore do
@@ -0,0 +1,90 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require "rbench"
5
+ require 'hashie'
6
+
7
+ require 'erector'
8
+ require File.dirname(__FILE__) + "/../../lib/garterbelt"
9
+
10
+ require File.dirname(__FILE__) + '/templates/garterbelt'
11
+ require File.dirname(__FILE__) + '/templates/erector'
12
+
13
+ TIMES = 10_000
14
+
15
+ RBench.run(TIMES) do
16
+ column :garterbelt
17
+ column :erector
18
+
19
+ user = Hashie::Mash.new(:username => 'baccigalupi', :email => 'baccigalupi@example.com', :name => 'Kane Baccigalupi')
20
+
21
+ report "Simple Page Initializing" do
22
+ garterbelt { GarterbeltTemplate.new(:user => user) }
23
+ erector { ErectorTemplate.new(:user => user) }
24
+ end
25
+
26
+ report "Simple Page Rendering" do
27
+ garterbelt { GarterbeltTemplate.new(:user => user).render }
28
+ erector { ErectorTemplate.new(:user => user).to_html }
29
+ end
30
+
31
+ report "Simple Page, class level rendering" do
32
+ garterbelt { GarterbeltTemplate.render(:user => user) }
33
+ erector { ErectorTemplate.new(:user => user).to_html }
34
+ end
35
+ end
36
+
37
+ # 4/13/2011, version 0.0.4, Removing RuPol from the lib, totally a flacid chick :(
38
+ # more work on performance later
39
+ # GARTERBELT | ERECTOR |
40
+ # -----------------------------------------------------------------
41
+ # Simple Page Initializing 0.178 | 0.173 | 2.8% slower
42
+ # Simple Page Rendering 7.132 | 6.601 | 7.4% slower
43
+
44
+ # 4/13/2011, version 0.0.4, Oops none of the benchmarks were rendering, just initializing
45
+ # and the performance sucks
46
+ # 10_000
47
+ # GARTERBELT | ERECTOR |
48
+ # -----------------------------------------------------------------
49
+ # Simple Page Initializing 0.200 | 0.176 | 12% slower
50
+ # Simple Page Rendering 24.488 | 6.815 | 72% slower
51
+ # Simple Page, class level rendering 24.594 | 6.775 | 72% slower
52
+
53
+
54
+ # 4/13/2011, version 0.0.4, performance regression
55
+ # 100_000
56
+ # GARTERBELT | ERECTOR |
57
+ # ----------------------------------------------------
58
+ # Simple Page Initialization 2.139 | 1.958 | 9.2% slower
59
+ # Simple Page Initialization 1.956 | 1.928 | 1.4% slower # removing opts.dup in view initialize
60
+ # Simple Page Initialization 1.595 | 1.929 | 17.2% faster # not passing the block in partial (feature withdrawal, not viable)
61
+ # Simple Page Initialization 1.663 | 1.914 | 13% faster # conditional passing of block in partial
62
+ # Simple Page Initialization 1.629 | 1.891 | 13.8% # conditional passing of block in other view methods
63
+
64
+ # 4/11/2011, version 0.0.1
65
+ # GARTERBELT = pooling at standard 1000 instances
66
+ # GARTERBELT_2 = pooling at 10% of sample time
67
+
68
+ # 10_000 times
69
+ # GARTERBELT | ERECTOR |
70
+ # ---------------------------------------------------------------------
71
+ # Simple Page Initialization 0.164 | 0.205 | 20% faster
72
+
73
+ # 100_000 times
74
+ # GARTERBELT | GARTERBELT_2 | ERECTOR |
75
+ # ---------------------------------------------------------------------
76
+ # Simple Page Initialization 1.857 | 1.828 | 1.932 | 3.8-5.3%/ faster
77
+
78
+ # 200_000 times
79
+ # GARTERBELT | GARTERBELT_2 | ERECTOR |
80
+ # ---------------------------------------------------------------------
81
+ # Simple Page Initialization 3.743 | 3.660 | 3.846 | 2.7-4.8% faster
82
+
83
+ # 500_000 times
84
+ # GARTERBELT | GARTERBELT_2 | ERECTOR |
85
+ # ---------------------------------------------------------------------
86
+ # Simple Page Initialization 9.420 | 9.422 | 9.637 | 2.3-2.2% faster
87
+
88
+
89
+
90
+
@@ -34,16 +34,6 @@ describe Garterbelt::ClosedTag do
34
34
  end
35
35
  end
36
36
 
37
- describe 'pooling' do
38
- it 'include RuPol::Swimsuit' do
39
- ClosedTag.ancestors.should include(RuPol::Swimsuit)
40
- end
41
-
42
- it 'has a really large max_pool_size' do
43
- ClosedTag._pool.max_size.should == 10000
44
- end
45
- end
46
-
47
37
  describe 'method chaining' do
48
38
  before do
49
39
  @tag = ClosedTag.new(:type => :input, :view => @view)
@@ -22,10 +22,6 @@ describe Garterbelt::Comment do
22
22
  ArgumentError, ":content option required for Garterbelt::Comment initialization"
23
23
  )
24
24
  end
25
-
26
- it 'has a smaller pool size' do
27
- Garterbelt::Comment._pool.max_size.should == 1000
28
- end
29
25
  end
30
26
 
31
27
  describe 'render' do
@@ -26,10 +26,6 @@ describe Garterbelt::ContentTag do
26
26
  @output << "This is block content"
27
27
  end.content.class.should == Proc
28
28
  end
29
-
30
- it 'inherits a really large max_pool_size' do
31
- ContentTag._pool.max_size.should == 10000
32
- end
33
29
  end
34
30
 
35
31
  describe 'chaining' do
@@ -9,10 +9,6 @@ describe Garterbelt::Doctype do
9
9
  it 'is decends from ClosedTag' do
10
10
  Garterbelt::Doctype.ancestors.should include Garterbelt::ClosedTag
11
11
  end
12
-
13
- it 'has a smaller pool size' do
14
- Garterbelt::Doctype._pool.max_size.should == 1000
15
- end
16
12
  end
17
13
 
18
14
  describe 'render' do
@@ -22,10 +22,6 @@ describe Garterbelt::Text do
22
22
  ArgumentError, ":content option required for Garterbelt::Text initialization"
23
23
  )
24
24
  end
25
-
26
- it 'inherits its pool size' do
27
- Garterbelt::Text._pool.max_size.should == 10000
28
- end
29
25
  end
30
26
 
31
27
  describe 'render' do
@@ -13,12 +13,6 @@ describe Garterbelt::View do
13
13
  @view = BasicView.new
14
14
  end
15
15
 
16
- describe 'pooling' do
17
- it 'includes the swimsuit' do
18
- BasicView.ancestors.should include( RuPol::Swimsuit )
19
- end
20
- end
21
-
22
16
  describe 'attributes' do
23
17
  it 'has a tag buffer' do
24
18
  @view.buffer.should == []
@@ -59,6 +53,18 @@ describe Garterbelt::View do
59
53
  end
60
54
  end
61
55
 
56
+ it 'can be initailzed with a block' do
57
+ view = BasicView.new do
58
+ Garterbelt::Tag.new(:type => :p, :content => 'Initalization block content', :view => view)
59
+ end
60
+ view.block.is_a?(Proc).should be_true
61
+ end
62
+
63
+ it 'can save the options' do
64
+ view = BasicView.new(:foo => 'foo', :bar => 'bar')
65
+ view.options.should == {:foo => 'foo', :bar => 'bar'}
66
+ end
67
+
62
68
  describe 'setting the curator: view responsible for displaying the rendered content' do
63
69
  before do
64
70
  @view.level = 42
@@ -54,10 +54,17 @@ describe Garterbelt::View, 'Partials' do
54
54
 
55
55
  it 'has the correct initalization options' do
56
56
  @view.partial(PartedOut, :x => '= foo')
57
- partial = @view
57
+ partial = @view.buffer.last
58
+ partial.x.should == '= foo'
58
59
  end
59
60
 
60
- it 'passes along the block, wait do views take blocks right now?'
61
+ it 'passes along the block' do
62
+ @view.partial(PartedOut, :x => 'not x') do
63
+ puts { 'maybe x; i don\'t know '}
64
+ end
65
+ partial = @view.buffer.last
66
+ partial.block.is_a?(Proc).should be_true
67
+ end
61
68
  end
62
69
  end
63
70
  end
@@ -58,19 +58,6 @@ describe Garterbelt::View do
58
58
  @view.render_buffer
59
59
  end
60
60
 
61
- it 'should recycle the tags' do
62
- @view.buffer << @hr << @input << @img
63
- @hr.stub(:render)
64
- @input.stub(:render)
65
- @img.stub(:render)
66
-
67
- @hr.should_receive(:recycle)
68
- @input.should_receive(:recycle)
69
- @img.should_receive(:recycle)
70
-
71
- @view.render_buffer
72
- end
73
-
74
61
  it 'will add non renderable items to the output as strings' do
75
62
  @view.buffer << "foo " << :bar
76
63
  @view.render_buffer
@@ -143,7 +130,6 @@ describe Garterbelt::View do
143
130
  describe 'class method' do
144
131
  before do
145
132
  @rendered = @view.render
146
- @view.stub(:recycle)
147
133
  end
148
134
 
149
135
  it 'makes a new view' do
@@ -163,20 +149,23 @@ describe Garterbelt::View do
163
149
  BasicView.render :method => :alt_content
164
150
  end
165
151
 
166
- it 'recycles the view' do
167
- BasicView.stub(:new).and_return(@view)
168
- @view.should_receive(:recycle)
169
- BasicView.render
170
- end
171
-
172
152
  it 'returns the output' do
173
153
  BasicView.stub(:new).and_return(@view)
174
154
  BasicView.render.should == @rendered
175
155
  end
176
156
  end
157
+
158
+ describe 'block initalized content' do
159
+ it 'has a #render_block method that renders that content' do
160
+ @view = BasicView.new do
161
+ @view.buffer << Garterbelt::ContentTag.new(:type => :p, :view => @view, :content => 'Block level p tag')
162
+ end
163
+ @view.render_block.should include "Block level p tag"
164
+ end
165
+ end
177
166
  end
178
167
 
179
- describe 'tag helpers' do
168
+ describe 'renderers' do
180
169
  describe '#tag' do
181
170
  it 'makes a new tag' do
182
171
  Garterbelt::ContentTag.should_receive(:new).with(
@@ -330,11 +319,11 @@ describe Garterbelt::View do
330
319
 
331
320
  describe 'comment' do
332
321
  it 'makes a comment object' do
333
- @view.comment('This is a comment.').is_a?(Garterbelt::Comment).should be_true
322
+ @view.comment_tag('This is a comment.').is_a?(Garterbelt::Comment).should be_true
334
323
  end
335
324
 
336
325
  it 'puts it on the buffer' do
337
- comment = @view.comment("new comment now")
326
+ comment = @view.comment_tag("new comment now")
338
327
  @view.buffer.last.should == comment
339
328
  end
340
329
  end
@@ -104,12 +104,22 @@ describe Garterbelt::View, 'Variables' do
104
104
  end
105
105
  end
106
106
 
107
- it 'raises on compile if the required variables map to existing methods' do
108
- lambda {
109
- class Failer < Garterbelt::View
110
- requires :p
111
- end
112
- }.should raise_error(ArgumentError, ":p cannot be a required variable because it maps to an existing method")
107
+ describe 'allowed accessors' do
108
+ it 'raises on compile if the required variables map to existing view methods' do
109
+ lambda {
110
+ class Failer < Garterbelt::View
111
+ requires :p
112
+ end
113
+ }.should raise_error(ArgumentError, ":p cannot be a required variable because it maps to an existing method")
114
+ end
115
+
116
+ it 'does not raise an error when overriding Object instance methods' do
117
+ lambda {
118
+ class Doer < Garterbelt::View
119
+ requires :tap
120
+ end
121
+ }.should_not raise_error
122
+ end
113
123
  end
114
124
  end
115
125
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: garterbelt
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 21
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 4
10
- version: 0.0.4
9
+ - 5
10
+ version: 0.0.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - Kane Baccigalupi
@@ -15,27 +15,11 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-04-12 00:00:00 -07:00
18
+ date: 2011-04-13 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  requirement: &id001 !ruby/object:Gem::Requirement
23
- none: false
24
- requirements:
25
- - - "="
26
- - !ruby/object:Gem::Version
27
- hash: 31
28
- segments:
29
- - 0
30
- - 1
31
- - 2
32
- version: 0.1.2
33
- type: :runtime
34
- name: ru_pol
35
- prerelease: false
36
- version_requirements: *id001
37
- - !ruby/object:Gem::Dependency
38
- requirement: &id002 !ruby/object:Gem::Requirement
39
23
  none: false
40
24
  requirements:
41
25
  - - ">="
@@ -49,9 +33,9 @@ dependencies:
49
33
  type: :runtime
50
34
  name: activesupport
51
35
  prerelease: false
52
- version_requirements: *id002
36
+ version_requirements: *id001
53
37
  - !ruby/object:Gem::Dependency
54
- requirement: &id003 !ruby/object:Gem::Requirement
38
+ requirement: &id002 !ruby/object:Gem::Requirement
55
39
  none: false
56
40
  requirements:
57
41
  - - ">="
@@ -65,9 +49,9 @@ dependencies:
65
49
  type: :runtime
66
50
  name: moneta
67
51
  prerelease: false
68
- version_requirements: *id003
52
+ version_requirements: *id002
69
53
  - !ruby/object:Gem::Dependency
70
- requirement: &id004 !ruby/object:Gem::Requirement
54
+ requirement: &id003 !ruby/object:Gem::Requirement
71
55
  none: false
72
56
  requirements:
73
57
  - - ~>
@@ -80,9 +64,9 @@ dependencies:
80
64
  type: :development
81
65
  name: hashie
82
66
  prerelease: false
83
- version_requirements: *id004
67
+ version_requirements: *id003
84
68
  - !ruby/object:Gem::Dependency
85
- requirement: &id005 !ruby/object:Gem::Requirement
69
+ requirement: &id004 !ruby/object:Gem::Requirement
86
70
  none: false
87
71
  requirements:
88
72
  - - ~>
@@ -96,9 +80,9 @@ dependencies:
96
80
  type: :development
97
81
  name: rspec
98
82
  prerelease: false
99
- version_requirements: *id005
83
+ version_requirements: *id004
100
84
  - !ruby/object:Gem::Dependency
101
- requirement: &id006 !ruby/object:Gem::Requirement
85
+ requirement: &id005 !ruby/object:Gem::Requirement
102
86
  none: false
103
87
  requirements:
104
88
  - - ~>
@@ -112,9 +96,9 @@ dependencies:
112
96
  type: :development
113
97
  name: yard
114
98
  prerelease: false
115
- version_requirements: *id006
99
+ version_requirements: *id005
116
100
  - !ruby/object:Gem::Dependency
117
- requirement: &id007 !ruby/object:Gem::Requirement
101
+ requirement: &id006 !ruby/object:Gem::Requirement
118
102
  none: false
119
103
  requirements:
120
104
  - - ~>
@@ -128,9 +112,9 @@ dependencies:
128
112
  type: :development
129
113
  name: bundler
130
114
  prerelease: false
131
- version_requirements: *id007
115
+ version_requirements: *id006
132
116
  - !ruby/object:Gem::Dependency
133
- requirement: &id008 !ruby/object:Gem::Requirement
117
+ requirement: &id007 !ruby/object:Gem::Requirement
134
118
  none: false
135
119
  requirements:
136
120
  - - ~>
@@ -144,9 +128,9 @@ dependencies:
144
128
  type: :development
145
129
  name: jeweler
146
130
  prerelease: false
147
- version_requirements: *id008
131
+ version_requirements: *id007
148
132
  - !ruby/object:Gem::Dependency
149
- requirement: &id009 !ruby/object:Gem::Requirement
133
+ requirement: &id008 !ruby/object:Gem::Requirement
150
134
  none: false
151
135
  requirements:
152
136
  - - ">="
@@ -158,9 +142,9 @@ dependencies:
158
142
  type: :development
159
143
  name: rcov
160
144
  prerelease: false
161
- version_requirements: *id009
145
+ version_requirements: *id008
162
146
  - !ruby/object:Gem::Dependency
163
- requirement: &id010 !ruby/object:Gem::Requirement
147
+ requirement: &id009 !ruby/object:Gem::Requirement
164
148
  none: false
165
149
  requirements:
166
150
  - - ~>
@@ -173,9 +157,9 @@ dependencies:
173
157
  type: :development
174
158
  name: hashie
175
159
  prerelease: false
176
- version_requirements: *id010
160
+ version_requirements: *id009
177
161
  - !ruby/object:Gem::Dependency
178
- requirement: &id011 !ruby/object:Gem::Requirement
162
+ requirement: &id010 !ruby/object:Gem::Requirement
179
163
  none: false
180
164
  requirements:
181
165
  - - ">="
@@ -187,25 +171,9 @@ dependencies:
187
171
  type: :development
188
172
  name: rbench
189
173
  prerelease: false
190
- version_requirements: *id011
191
- - !ruby/object:Gem::Dependency
192
- requirement: &id012 !ruby/object:Gem::Requirement
193
- none: false
194
- requirements:
195
- - - ">="
196
- - !ruby/object:Gem::Version
197
- hash: 31
198
- segments:
199
- - 0
200
- - 1
201
- - 2
202
- version: 0.1.2
203
- type: :runtime
204
- name: ru_pol
205
- prerelease: false
206
- version_requirements: *id012
174
+ version_requirements: *id010
207
175
  - !ruby/object:Gem::Dependency
208
- requirement: &id013 !ruby/object:Gem::Requirement
176
+ requirement: &id011 !ruby/object:Gem::Requirement
209
177
  none: false
210
178
  requirements:
211
179
  - - ">="
@@ -219,9 +187,9 @@ dependencies:
219
187
  type: :runtime
220
188
  name: activesupport
221
189
  prerelease: false
222
- version_requirements: *id013
190
+ version_requirements: *id011
223
191
  - !ruby/object:Gem::Dependency
224
- requirement: &id014 !ruby/object:Gem::Requirement
192
+ requirement: &id012 !ruby/object:Gem::Requirement
225
193
  none: false
226
194
  requirements:
227
195
  - - ">="
@@ -235,7 +203,7 @@ dependencies:
235
203
  type: :runtime
236
204
  name: moneta
237
205
  prerelease: false
238
- version_requirements: *id014
206
+ version_requirements: *id012
239
207
  description: Garterbelt is a Ruby HTML/XML markup framework inspired by Erector and Markaby. Garterbelt maps html tags to methods allowing the intuitive construction of HTML pages using nothing but Ruby. And because it is all Ruby all the time, views benefit from the dryness of inheritance, modules and all the meta magic that Ruby can imagine. Stockings not included.
240
208
  email: baccigalupi@gmail.com
241
209
  executables: []
@@ -271,23 +239,27 @@ files:
271
239
  - lib/stocking.rb
272
240
  - lib/support/string.rb
273
241
  - lib/view.rb
274
- - spec/benchmark/templates/erector.rb
275
- - spec/benchmark/templates/garterbelt.rb
276
- - spec/benchmark/vs_erector.rb
277
242
  - spec/garterbelt_spec.rb
278
243
  - spec/integration/expectations/general_view.html
279
244
  - spec/integration/expectations/variables/view_with_user_and_params.html
280
245
  - spec/integration/expectations/variables/view_with_user_email.html
281
246
  - spec/integration/expectations/view_partial_nest.html
247
+ - spec/integration/expectations/view_with_forms.html
282
248
  - spec/integration/expectations/view_with_tags.html
249
+ - spec/integration/templates/form.rb
283
250
  - spec/integration/templates/view_partial_nest.rb
284
251
  - spec/integration/templates/view_with_cache.rb
252
+ - spec/integration/templates/view_with_forms.rb
285
253
  - spec/integration/templates/view_with_partial.rb
286
254
  - spec/integration/templates/view_with_partial_2.rb
287
255
  - spec/integration/templates/view_with_tags.rb
288
256
  - spec/integration/templates/view_with_vars.rb
289
257
  - spec/integration/view_spec.rb
290
258
  - spec/page_spec.rb
259
+ - spec/performance/profiling.rb
260
+ - spec/performance/templates/erector.rb
261
+ - spec/performance/templates/garterbelt.rb
262
+ - spec/performance/vs_erector.rb
291
263
  - spec/renderers/cache_spec.rb
292
264
  - spec/renderers/closed_tag_spec.rb
293
265
  - spec/renderers/comment_spec.rb
@@ -338,18 +310,21 @@ signing_key:
338
310
  specification_version: 3
339
311
  summary: Garterbelt is a Ruby HTML/XML markup framework. It is san DSL. Just all Ruby, all the time.
340
312
  test_files:
341
- - spec/benchmark/templates/erector.rb
342
- - spec/benchmark/templates/garterbelt.rb
343
- - spec/benchmark/vs_erector.rb
344
313
  - spec/garterbelt_spec.rb
314
+ - spec/integration/templates/form.rb
345
315
  - spec/integration/templates/view_partial_nest.rb
346
316
  - spec/integration/templates/view_with_cache.rb
317
+ - spec/integration/templates/view_with_forms.rb
347
318
  - spec/integration/templates/view_with_partial.rb
348
319
  - spec/integration/templates/view_with_partial_2.rb
349
320
  - spec/integration/templates/view_with_tags.rb
350
321
  - spec/integration/templates/view_with_vars.rb
351
322
  - spec/integration/view_spec.rb
352
323
  - spec/page_spec.rb
324
+ - spec/performance/profiling.rb
325
+ - spec/performance/templates/erector.rb
326
+ - spec/performance/templates/garterbelt.rb
327
+ - spec/performance/vs_erector.rb
353
328
  - spec/renderers/cache_spec.rb
354
329
  - spec/renderers/closed_tag_spec.rb
355
330
  - spec/renderers/comment_spec.rb
@@ -1,53 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'rubygems'
4
- require "rbench"
5
- require 'hashie'
6
-
7
- require 'erector'
8
- require File.dirname(__FILE__) + "/../../lib/garterbelt"
9
-
10
- require File.dirname(__FILE__) + '/templates/stocking'
11
- require File.dirname(__FILE__) + '/templates/erector'
12
-
13
- TIMES = 500_000
14
-
15
- RBench.run(TIMES) do
16
- LoungeTemplate.max_pool_size TIMES/10
17
- column :garterbelt
18
- column :erector
19
-
20
- report "Simple Page Rendering" do
21
- user = Hashie::Mash.new(:username => 'baccigalupi', :email => 'baccigalupi@example.com', :name => 'Kane Baccigalupi')
22
- erector { ErectorTemplate.new(:user => user) }
23
- garterbelt { GarterbeltTemplate.new(:user => user) }
24
- end
25
- end
26
-
27
- # 4/11/2011, version 0.0.1, standard pooling
28
- # GARTERBELT = pooling at standard 1000 instances
29
- # GARTERBELT_2 = pooling at 10% of sample time
30
-
31
- # 10_000 times
32
- # GARTERBELT | ERECTOR |
33
- # ---------------------------------------------------------------------
34
- # Simple Page Rendering 0.164 | 0.205 | 20% faster
35
-
36
- # 100_000 times
37
- # GARTERBELT | GARTERBELT_2 | ERECTOR |
38
- # ---------------------------------------------------------------------
39
- # Simple Page Rendering 1.857 | 1.828 | 1.932 | 3.8-5.3%/ faster
40
-
41
- # 200_000 times
42
- # GARTERBELT | GARTERBELT_2 | ERECTOR |
43
- # ---------------------------------------------------------------------
44
- # Simple Page Rendering 3.743 | 3.660 | 3.846 | 2.7-4.8% faster
45
-
46
- # 500_000 times
47
- # GARTERBELT | GARTERBELT_2 | ERECTOR |
48
- # ---------------------------------------------------------------------
49
- # Simple Page Rendering 9.420 | 9.422 | 9.637 | 2.3-2.2% faster
50
-
51
-
52
-
53
-