ruhl 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -2,3 +2,4 @@
2
2
  *.swp
3
3
  pkg/**
4
4
  coverage/**
5
+ test.log
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.2.0
1
+ 1.3.0
data/lib/ruhl.rb CHANGED
@@ -10,6 +10,7 @@ module Ruhl
10
10
  attr_accessor :logger, :encoding
11
11
  attr_accessor :inspect_local_object, :inspect_block_object
12
12
  attr_accessor :inspect_scope
13
+ attr_accessor :use_instance_variables, :log_instance_variable_warning
13
14
  end
14
15
 
15
16
  self.logger = Logger.new(STDOUT)
@@ -19,4 +20,7 @@ module Ruhl
19
20
  self.inspect_local_object = false
20
21
  self.inspect_block_object = false
21
22
  self.inspect_scope = false
23
+
24
+ self.use_instance_variables = true
25
+ self.log_instance_variable_warning = true
22
26
  end
data/lib/ruhl/engine.rb CHANGED
@@ -44,7 +44,7 @@ module Ruhl
44
44
  def render_with_layout
45
45
  raise LayoutNotFoundError.new(@layout) unless File.exists?(@layout)
46
46
 
47
- render_nodes Nokogiri::HTML( @layout_source || File.read(@layout) )
47
+ render_nodes Nokogiri::HTML( @layout_source || file_contents(@layout) )
48
48
  end
49
49
 
50
50
  def render_partial
@@ -52,7 +52,7 @@ module Ruhl
52
52
  raise PartialNotFoundError.new(call_result)
53
53
  end
54
54
 
55
- render_nodes Nokogiri::HTML.fragment( File.read(call_result) )
55
+ render_nodes Nokogiri::HTML.fragment( file_contents(call_result) )
56
56
  end
57
57
 
58
58
  def render_collection
@@ -64,7 +64,7 @@ module Ruhl
64
64
  new_content = call_result.collect do |item|
65
65
 
66
66
  if actions.empty? && current_tag.xpath('.//*[@data-ruhl]').empty?
67
- if item.is_a?(Hash)
67
+ if item.kind_of?(Hash)
68
68
  t = current_tag.dup
69
69
  apply_hash(t, item)
70
70
  t.to_html
@@ -131,7 +131,7 @@ module Ruhl
131
131
  if attribute =~ /^_/
132
132
  send("ruhl#{attribute}")
133
133
  else
134
- current_tag[attribute] = call_result.to_s
134
+ write_tag_attribute(current_tag, attribute, call_result)
135
135
  end
136
136
  end
137
137
  rescue NoMethodError => nme
@@ -195,7 +195,7 @@ module Ruhl
195
195
  end
196
196
 
197
197
  def process_results
198
- if call_result.is_a?(Hash)
198
+ if call_result.kind_of?(Hash)
199
199
  apply_hash(current_tag, call_result)
200
200
  else
201
201
  current_tag.inner_html = call_result.to_s
@@ -207,30 +207,52 @@ module Ruhl
207
207
  if key == :inner_html
208
208
  tag.inner_html = value.to_s
209
209
  else
210
- tag[key.to_s] = value.to_s
210
+ write_tag_attribute(tag, key.to_s, value)
211
211
  end
212
212
  end
213
213
  end
214
214
 
215
+ def write_tag_attribute(tag, attribute, value)
216
+ if tag[attribute] && attribute.downcase == 'class'
217
+ tag[attribute] = "#{tag[attribute]} #{value}"
218
+ else
219
+ tag[attribute] = value.to_s
220
+ end
221
+ end
222
+
215
223
  def execute_ruby(code)
216
224
  if code == '_render_'
217
225
  _render_
218
226
  else
219
227
  args = code.strip.split('|').collect{|p| p.strip}
220
228
 
221
- if block_object.respond_to?(args.first)
222
- block_object.send(*args)
223
- elsif local_object.respond_to?(args.first)
224
- local_object.send(*args)
225
- else
226
- scope.send(*args)
229
+ [block_object, local_object, scope].compact.each do |obj|
230
+ return call_to(obj, args) rescue NoMethodError
231
+ end
232
+
233
+ if Ruhl.use_instance_variables
234
+ # No luck so far, lets see if code is actually an instance
235
+ # variable.
236
+ ivar = :"@#{code}"
237
+ if scope.instance_variable_defined?(ivar)
238
+ if Ruhl.log_instance_variable_warning
239
+ Ruhl.logger.warn("Ruhl did NOT find a method named: #{code} but did find and is using: @#{code}")
240
+ end
241
+ return scope.instance_variable_get(ivar)
242
+ end
227
243
  end
244
+
245
+ log_context(code)
246
+ raise NoMethodError.new("Neither method nor instance variable found: #{args.first}")
247
+ end
248
+ end
249
+
250
+ def call_to(object, args)
251
+ if object.kind_of?(Hash) && ( object.has_key?(args.first) || object.has_key?(args.first.to_sym))
252
+ object[args.first] || object[args.first.to_sym]
253
+ else
254
+ object.send(*args)
228
255
  end
229
- rescue NoMethodError => nme
230
- Ruhl.logger.error(nme.message)
231
- Ruhl.logger.error(nme.backtrace.join("\n"))
232
- log_context(code)
233
- raise nme
234
256
  end
235
257
 
236
258
  def set_scope(current_scope)
@@ -250,8 +272,8 @@ module Ruhl
250
272
 
251
273
  def call_result_populated_array?
252
274
  call_result.kind_of?(Array) && !call_result.empty?
253
-
254
275
  end
276
+
255
277
  def call_result_empty_array?
256
278
  call_result.kind_of?(Array) && call_result.empty?
257
279
  end
@@ -279,5 +301,19 @@ CONTEXT
279
301
  send(object_str).class.to_s
280
302
  end
281
303
  end
304
+
305
+ if RUBY_VERSION == '1.8.6'
306
+ def file_contents(path_to_file)
307
+ File.open(path_to_file,'r') do |f|
308
+ f.read
309
+ end
310
+ end
311
+ else
312
+ def file_contents(path_to_file)
313
+ File.open(path_to_file, "r:#{Ruhl.encoding}") do |f|
314
+ f.read
315
+ end
316
+ end
317
+ end
282
318
  end # Engine
283
319
  end # Ruhl
data/ruhl.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{ruhl}
8
- s.version = "1.2.0"
8
+ s.version = "1.3.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Andrew Stone"]
12
- s.date = %q{2010-02-01}
12
+ s.date = %q{2010-02-10}
13
13
  s.description = %q{Make your HTML dynamic with the addition of a data-ruhl attribute.}
14
14
  s.email = %q{andy@stonean.com}
15
15
  s.extra_rdoc_files = [
@@ -34,6 +34,7 @@ Gem::Specification.new do |s|
34
34
  "spec/html/basic.html",
35
35
  "spec/html/collection_of_hashes.html",
36
36
  "spec/html/collection_of_strings.html",
37
+ "spec/html/combination.html",
37
38
  "spec/html/form.html",
38
39
  "spec/html/fragment.html",
39
40
  "spec/html/hash.html",
@@ -44,7 +45,6 @@ Gem::Specification.new do |s|
44
45
  "spec/html/loop.html",
45
46
  "spec/html/main_with_form.html",
46
47
  "spec/html/main_with_sidebar.html",
47
- "spec/html/medium.html",
48
48
  "spec/html/parameters.html",
49
49
  "spec/html/seo.html",
50
50
  "spec/html/sidebar.html",
@@ -0,0 +1,32 @@
1
+ <html>
2
+ <head>
3
+ <title>This is a title template</title>
4
+ </head>
5
+ <body>
6
+ <h1>This is the header template</h1>
7
+ <p id='time'>It is now <span data-ruhl='_swap:time'/> time</p>
8
+ <table>
9
+ <thead>
10
+ <tr>
11
+ <td>First Name</td>
12
+ <td>Last Name</td>
13
+ <td>Email</td>
14
+ </tr>
15
+ </thead>
16
+ <tbody>
17
+ <tr class='user_data' data-ruhl="_collection: user_list, class: user_id">
18
+ <td data-ruhl="first_name">Andrew</td>
19
+ <td data-ruhl="last_name">Stone</td>
20
+ <td data-ruhl="email">andy@stonean.com</td>
21
+ </tr>
22
+ </tbody>
23
+ </table>
24
+ </ul>
25
+
26
+ <ul id="ruby_urls">
27
+ <li data-ruhl="_use: ruby_urls">
28
+ <a href="http://rubytrends.com" data-ruhl="href: href, name">RubyTrends</a>
29
+ </li>
30
+ </ul>
31
+ </body>
32
+ </html>
data/spec/ruhl_spec.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # encoding: UTF-8
1
2
  require File.join(File.dirname(__FILE__), 'spec_helper')
2
3
 
3
4
  describe Ruhl do
@@ -34,25 +35,59 @@ describe Ruhl do
34
35
  end
35
36
  end
36
37
 
37
- describe "medium.html" do
38
+ describe "combination.html" do
38
39
  before do
39
- @html = File.read html(:medium)
40
- @doc = create_doc
40
+ @html = File.read html(:combination)
41
41
  end
42
42
 
43
- it "first data row should equal first user " do
44
- table = @doc.xpath('/html/body/table/tr//td')
43
+ it 'first data row should equal first user' do
44
+ doc = create_doc
45
+ table = doc.xpath('/html/body/table/tbody/tr//td')
45
46
  table.children[0].to_s.should == "Jane"
46
47
  table.children[1].to_s.should == "Doe"
47
48
  table.children[2].to_s.should == "jane@stonean.com"
48
49
  end
49
50
 
50
- it "last data row should equal last user " do
51
- table = @doc.xpath('/html/body/table/tr//td')
51
+ it 'last data row should equal last user' do
52
+ doc = create_doc
53
+ table = doc.xpath('/html/body/table/tbody/tr//td')
52
54
  table.children[9].to_s.should == "Paul"
53
55
  table.children[10].to_s.should == "Tin"
54
56
  table.children[11].to_s.should == "paul@stonean.com"
55
57
  end
58
+
59
+ it 'should append user_id to class' do
60
+ doc = create_doc
61
+ rows = doc.xpath('/html/body/table/tbody//tr')
62
+ rows.each do |row|
63
+ row['class'].should =~ /^user_data user_\d+$/
64
+ end
65
+ end
66
+
67
+ it 'should set href from hash' do
68
+ doc = create_doc
69
+ rows = doc.xpath("/html/body/ul[@id='ruby_urls']/li//a")
70
+ rows[0].inner_html.should == 'Ruby Lang'
71
+ rows[0]['href'].should == 'http://ruby-lang.org'
72
+ rows[1].inner_html.should == 'RubyonRails'
73
+ rows[1]['href'].should == 'http://rubyonrails.com'
74
+ rows[2].inner_html.should == 'RubyFlow'
75
+ rows[2]['href'].should == 'http://rubyflow.com'
76
+ rows[3].inner_html.should == 'RubyTrends'
77
+ rows[3]['href'].should == 'http://rubytrends.com'
78
+ end
79
+
80
+ it 'should use instance variable' do
81
+ doc = create_doc
82
+ p = doc.xpath("/html/body/p[@id='time']")
83
+ p.inner_html.should == 'It is now Peanut Butter Jelly time'
84
+ end
85
+
86
+ it 'should not use instance variable' do
87
+ Ruhl.use_instance_variables = false
88
+ lambda{ create_doc }.should raise_error(NoMethodError)
89
+ Ruhl.use_instance_variables = true
90
+ end
56
91
  end
57
92
 
58
93
  describe "fragment.html" do
@@ -362,6 +397,11 @@ describe Ruhl do
362
397
  options = @doc.xpath('/html/body/select//option')
363
398
  options.children.length.should == @co.state_options.length
364
399
  end
400
+
401
+ it "should have selected Georgia" do
402
+ state = @doc.xpath('/html/body/select//option[@selected]')
403
+ state[0]['value'].should == "GA"
404
+ end
365
405
  end
366
406
  end
367
407
 
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), %w[.. lib ruhl]))
2
2
 
3
+ Ruhl.logger = Logger.new('test.log')
4
+
3
5
  def html(name)
4
6
  File.join( File.dirname(__FILE__), 'html', "#{name}.html" )
5
7
  end
@@ -30,9 +32,13 @@ class TestUser
30
32
  end
31
33
 
32
34
  def radio_input
33
- { :inner_html => first_name, :id => "user_#{id.to_s}",
35
+ { :inner_html => first_name, :id => user_id,
34
36
  :name => "user[id]", :value => last_name.downcase}
35
37
  end
38
+
39
+ def user_id
40
+ "user_#{id}"
41
+ end
36
42
  end
37
43
 
38
44
  def user
@@ -41,6 +47,10 @@ end
41
47
 
42
48
 
43
49
  class ContextObject
50
+ def initialize
51
+ @time = 'Peanut Butter Jelly'
52
+ end
53
+
44
54
  def language
45
55
  'Ruby'
46
56
  end
@@ -163,7 +173,7 @@ class ContextObject
163
173
  {:value => 'CT', :inner_html => 'Connecticut'},
164
174
  {:value => 'DE', :inner_html => 'Delaware'},
165
175
  {:value => 'FL', :inner_html => 'Florida'},
166
- {:value => 'GA', :inner_html => 'Georgia'},
176
+ {:value => 'GA', :inner_html => 'Georgia', :selected => true},
167
177
  {:value => 'HI', :inner_html => 'Hawaii'},
168
178
  {:value => 'ID', :inner_html => 'Idaho'},
169
179
  {:value => 'IL', :inner_html => 'Illinois'},
@@ -210,6 +220,14 @@ class ContextObject
210
220
  {:class => "pretty", :id => "8675309", :inner_html => "jenny"}
211
221
  end
212
222
 
223
+ def ruby_urls
224
+ [
225
+ {:name => 'Ruby Lang', :href => 'http://ruby-lang.org'},
226
+ {'name' => 'RubyonRails', :href => 'http://rubyonrails.com'},
227
+ {:name => 'RubyFlow', 'href' => 'http://rubyflow.com'},
228
+ {'name' => 'RubyTrends', 'href' => 'http://rubytrends.com'}
229
+ ]
230
+ end
213
231
  end
214
232
 
215
233
  def points_of_interest
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruhl
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Stone
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-02-01 00:00:00 -05:00
12
+ date: 2010-02-10 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -59,6 +59,7 @@ files:
59
59
  - spec/html/basic.html
60
60
  - spec/html/collection_of_hashes.html
61
61
  - spec/html/collection_of_strings.html
62
+ - spec/html/combination.html
62
63
  - spec/html/form.html
63
64
  - spec/html/fragment.html
64
65
  - spec/html/hash.html
@@ -69,7 +70,6 @@ files:
69
70
  - spec/html/loop.html
70
71
  - spec/html/main_with_form.html
71
72
  - spec/html/main_with_sidebar.html
72
- - spec/html/medium.html
73
73
  - spec/html/parameters.html
74
74
  - spec/html/seo.html
75
75
  - spec/html/sidebar.html
@@ -1,23 +0,0 @@
1
- <html>
2
- <head>
3
- <title>This is a title template</title>
4
- </head>
5
- <body>
6
- <h1>This is the header template</h1>
7
- <table>
8
- <thead>
9
- <tr>
10
- <td>First Name</td>
11
- <td>Last Name</td>
12
- <td>Email</td>
13
- </tr>
14
- </thead>
15
- <tr data-ruhl="_collection: user_list">
16
- <td data-ruhl="first_name">Andrew</td>
17
- <td data-ruhl="last_name">Stone</td>
18
- <td data-ruhl="email">andy@stonean.com</td>
19
- </tr>
20
- </table>
21
- </ul>
22
- </body>
23
- </html>