manveru-innate 2009.04 → 2009.04.01

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. data/CHANGELOG +0 -258
  2. data/MANIFEST +22 -23
  3. data/README.md +9 -1
  4. data/Rakefile +6 -6
  5. data/example/app/retro_games.rb +8 -8
  6. data/example/app/todo/layout/{default.xhtml → default.erb} +1 -1
  7. data/example/app/todo/view/{index.xhtml → index.erb} +11 -11
  8. data/example/app/whywiki_erb/start.rb +1 -2
  9. data/example/app/whywiki_erb/view/{edit.erb → edit.html.erb} +0 -0
  10. data/example/app/whywiki_erb/view/{index.erb → index.html.erb} +0 -0
  11. data/example/howto_spec.rb +1 -1
  12. data/example/provides.rb +6 -9
  13. data/example/session.rb +3 -3
  14. data/innate.gemspec +14 -6
  15. data/lib/innate.rb +18 -12
  16. data/lib/innate/action.rb +11 -22
  17. data/lib/innate/cache/file_based.rb +0 -2
  18. data/lib/innate/core_compatibility/basic_object.rb +10 -0
  19. data/lib/innate/core_compatibility/string.rb +3 -0
  20. data/lib/innate/dynamap.rb +0 -5
  21. data/lib/innate/helper.rb +29 -20
  22. data/lib/innate/helper/cgi.rb +19 -32
  23. data/lib/innate/helper/link.rb +2 -2
  24. data/lib/innate/helper/partial.rb +93 -0
  25. data/lib/innate/helper/redirect.rb +1 -1
  26. data/lib/innate/helper/send_file.rb +1 -9
  27. data/lib/innate/mock.rb +3 -2
  28. data/lib/innate/node.rb +51 -78
  29. data/lib/innate/options.rb +1 -1
  30. data/lib/innate/request.rb +23 -3
  31. data/lib/innate/response.rb +7 -0
  32. data/lib/innate/session.rb +2 -1
  33. data/lib/innate/spec.rb +50 -6
  34. data/lib/innate/version.rb +1 -1
  35. data/lib/innate/view/erb.rb +1 -1
  36. data/lib/innate/view/etanni.rb +2 -2
  37. data/lib/innate/view/none.rb +1 -1
  38. data/spec/example/session.rb +14 -8
  39. data/spec/innate/action/layout.rb +1 -1
  40. data/spec/innate/action/layout/file_layout.erb +1 -0
  41. data/spec/innate/helper/aspect.rb +6 -6
  42. data/spec/innate/helper/flash.rb +47 -28
  43. data/spec/innate/helper/link.rb +0 -8
  44. data/spec/innate/helper/partial.rb +101 -0
  45. data/spec/innate/helper/redirect.rb +43 -58
  46. data/spec/innate/helper/view/aspect_hello.erb +1 -0
  47. data/spec/innate/helper/view/locals.erb +1 -0
  48. data/spec/innate/helper/view/loop.erb +4 -0
  49. data/spec/innate/helper/view/num.erb +1 -0
  50. data/spec/innate/helper/view/partial.erb +1 -0
  51. data/spec/innate/helper/view/recursive.erb +8 -0
  52. data/spec/innate/node/node.rb +13 -5
  53. data/spec/innate/node/view/another_layout/{another_layout.xhtml → another_layout.erb} +1 -1
  54. data/spec/innate/node/view/{bar.xhtml → bar.erb} +0 -0
  55. data/spec/innate/node/view/foo.html.erb +1 -0
  56. data/spec/innate/node/view/{only_view.xhtml → only_view.erb} +0 -0
  57. data/spec/innate/node/view/with_layout.erb +1 -0
  58. data/spec/innate/provides.rb +2 -2
  59. data/spec/innate/provides/list.html.erb +1 -0
  60. data/spec/innate/provides/list.txt.erb +1 -0
  61. data/spec/innate/session.rb +15 -14
  62. data/spec/innate/state/fiber.rb +7 -8
  63. data/tasks/bacon.rake +21 -38
  64. data/tasks/install_dependencies.rake +4 -2
  65. data/tasks/release.rake +9 -48
  66. metadata +57 -29
  67. data/lib/innate/helper/render.rb +0 -87
  68. data/spec/example/app/retro_games.rb +0 -30
  69. data/spec/example/provides.rb +0 -16
  70. data/spec/innate/action/layout/file_layout.xhtml +0 -1
  71. data/spec/innate/helper/render.rb +0 -133
  72. data/spec/innate/helper/view/aspect_hello.xhtml +0 -1
  73. data/spec/innate/helper/view/locals.xhtml +0 -1
  74. data/spec/innate/helper/view/loop.xhtml +0 -4
  75. data/spec/innate/helper/view/num.xhtml +0 -1
  76. data/spec/innate/helper/view/partial.xhtml +0 -1
  77. data/spec/innate/helper/view/recursive.xhtml +0 -7
  78. data/spec/innate/node/view/foo.html.xhtml +0 -1
  79. data/spec/innate/node/view/with_layout.xhtml +0 -1
  80. data/spec/innate/provides/list.html.xhtml +0 -1
  81. data/spec/innate/provides/list.txt.xhtml +0 -1
  82. data/tasks/setup.rake +0 -28
@@ -2,7 +2,7 @@ module Innate
2
2
  # this has to be run after a couple of other files have been required
3
3
 
4
4
  options.dsl do
5
- o "Innate::start will not start an adapter if true",
5
+ o "Indicate that calls Innate::start will be ignored",
6
6
  :started, false
7
7
 
8
8
  o "Will send ::setup to each element during Innate::start",
@@ -71,7 +71,7 @@ module Innate
71
71
  # Both +value+ and the elements of +keys+ will be turned into String by #to_s.
72
72
  def [](value, *keys)
73
73
  return super(value) if keys.empty?
74
- [value, *keys].map{|key| super(key) }
74
+ [value, *keys].map{|k| super(k) }
75
75
  end
76
76
 
77
77
  # the full request URI provided by Rack::Request
@@ -94,8 +94,8 @@ module Innate
94
94
  # # => {'name' => 'jason', 'job' => 'lumberjack'}
95
95
 
96
96
  def subset(*keys)
97
- keys = keys.map{|key| key.to_s }
98
- params.reject{|key, value| not keys.include?(key) }
97
+ keys = keys.map{|k| k.to_s }
98
+ params.reject{|k,v| not keys.include?(k) }
99
99
  end
100
100
 
101
101
  # Try to figure out the domain we are running on, this might work for some
@@ -137,5 +137,25 @@ module Innate
137
137
  rescue ArgumentError => ex
138
138
  raise ArgumentError, ex unless ex.message == 'invalid address'
139
139
  end
140
+
141
+ REQUEST_STRING_FORMAT = "#<%s params=%p cookies=%p env=%p>"
142
+
143
+ def to_s
144
+ REQUEST_STRING_FORMAT % [self.class, params, cookies, http_variables]
145
+ end
146
+ alias inspect to_s
147
+
148
+ # Pretty prints current action with parameters, cookies and enviroment
149
+ # variables.
150
+ def pretty_print(pp)
151
+ pp.object_group(self){
152
+ group = { 'params' => params, 'cookies' => cookies, 'env' => http_vars }
153
+ group.each do |name, hash|
154
+ pp.breakable
155
+ pp.text " @#{name}="
156
+ pp.nest(name.size + 3){ pp.pp_hash(hash) }
157
+ end
158
+ }
159
+ end
140
160
  end
141
161
  end
@@ -1,4 +1,9 @@
1
1
  module Innate
2
+
3
+ # In order to reset the body contents we also need to reset the length set by
4
+ # Response#write - until I can submit a patch to Rack and the next release we
5
+ # just do this.
6
+
2
7
  class Response < Rack::Response
3
8
  include Optioned
4
9
 
@@ -7,6 +12,8 @@ module Innate
7
12
  :headers, {'Content-Type' => 'text/html'}
8
13
  end
9
14
 
15
+ attr_accessor :length
16
+
10
17
  def reset
11
18
  self.status = 200
12
19
  self.header.delete('Content-Type')
@@ -62,7 +62,8 @@ module Innate
62
62
  end
63
63
 
64
64
  def flush(response = @response)
65
- return if !@cache_sid or @cache_sid.empty?
65
+ return unless @cache_sid
66
+ return if @cache_sid.empty?
66
67
 
67
68
  flash.rotate!
68
69
  ttl = (Time.at(cookie_value[:expires]) - Time.now).to_i
@@ -1,10 +1,10 @@
1
- begin; require 'rubygems'; rescue LoadError; end
2
-
3
1
  require 'bacon'
4
- require 'rack/test'
5
- require(File.expand_path("#{__FILE__}/../")) unless defined?(Innate)
6
2
 
7
3
  Bacon.summary_on_exit
4
+ # Bacon.extend(Bacon::TestUnitOutput)
5
+
6
+ innate = File.expand_path(File.join(File.dirname(__FILE__), '../innate'))
7
+ require(innate) unless defined?(Innate)
8
8
 
9
9
  module Innate
10
10
  # minimal middleware, no exception handling
@@ -15,9 +15,53 @@ module Innate
15
15
  options.mode = :spec
16
16
  end
17
17
 
18
+ # Shortcut to use persistent cookies via Innate::Mock::Session
19
+ #
20
+ # Usage:
21
+ #
22
+ # describe 'something' do
23
+ # behaves_like :session
24
+ #
25
+ # should 'get some stuff' do
26
+ # session do |mock|
27
+ # mock.get('/')
28
+ # end
29
+ # end
30
+ # end
31
+ shared :session do
32
+ Innate.setup_dependencies
33
+
34
+ def session(&block)
35
+ Innate::Mock.session(&block)
36
+ end
37
+ end
38
+
18
39
  shared :mock do
19
40
  Innate.setup_dependencies
20
- extend Rack::Test::Methods
21
41
 
22
- def app; Innate.middleware; end
42
+ def get(*args) Innate::Mock.get(*args) end
43
+ def post(*args) Innate::Mock.post(*args) end
44
+ def put(*args) Innate::Mock.put(*args) end
45
+ def delete(*args) Innate::Mock.delete(*args) end
46
+ end
47
+
48
+ shared :multipart do
49
+ def multipart(hash)
50
+ boundary = 'MuLtIpArT56789'
51
+ data = []
52
+ hash.each do |key, value|
53
+ data << "--#{boundary}"
54
+ data << %(Content-Disposition: form-data; name="#{key}")
55
+ data << '' << value
56
+ end
57
+ data << "--#{boundary}--"
58
+ body = data.join("\r\n")
59
+
60
+ type = "multipart/form-data; boundary=#{boundary}"
61
+ length = body.respond_to?(:bytesize) ? body.bytesize : body.size
62
+
63
+ { 'CONTENT_TYPE' => type,
64
+ 'CONTENT_LENGTH' => length.to_s,
65
+ :input => StringIO.new(body) }
66
+ end
23
67
  end
@@ -1,3 +1,3 @@
1
1
  module Innate
2
- VERSION = "2009.04"
2
+ VERSION = "2009.04.01"
3
3
  end
@@ -4,7 +4,7 @@ module Innate
4
4
  module View
5
5
  module ERB
6
6
  def self.call(action, string)
7
- erb = ::ERB.new(string.to_s, nil, '%<>')
7
+ erb = ::ERB.new(string.to_str, nil, '%<>')
8
8
  erb.filename = (action.view || action.method).to_s
9
9
  html = erb.result(action.binding)
10
10
 
@@ -2,7 +2,7 @@ module Innate
2
2
  module View
3
3
  module Etanni
4
4
  def self.call(action, string)
5
- template = Innate::Etanni.new(string.to_s)
5
+ template = Innate::Etanni.new(string.to_str)
6
6
  html = template.result(action.binding, (action.view || action.method))
7
7
  return html, 'text/html'
8
8
  end
@@ -18,7 +18,7 @@ module Innate
18
18
  def compile
19
19
  temp = @template.dup
20
20
  start_heredoc = "T" << Digest::SHA1.hexdigest(temp)
21
- start_heredoc, end_heredoc = "\n<<#{start_heredoc}.chomp\n", "\n#{start_heredoc}\n"
21
+ start_heredoc, end_heredoc = "\n<<#{start_heredoc}\n", "\n#{start_heredoc}\n"
22
22
  bufadd = "_out_ << "
23
23
 
24
24
  temp.gsub!(/<\?r\s+(.*?)\s+\?>/m,
@@ -2,7 +2,7 @@ module Innate
2
2
  module View
3
3
  module None
4
4
  def self.call(action, string)
5
- return string.to_s, 'text/html'
5
+ return string, 'text/html'
6
6
  end
7
7
  end
8
8
  end
@@ -2,21 +2,27 @@ require 'spec/helper'
2
2
  require 'example/session'
3
3
 
4
4
  describe 'example/session' do
5
- behaves_like :mock
5
+ behaves_like :session
6
6
 
7
7
  it 'starts at 0' do
8
- get('/').body.should =~ /Value is: 0/
8
+ session do |mock|
9
+ mock.get('/').should =~ /Value is: 0/
10
+ end
9
11
  end
10
12
 
11
13
  it 'increments the counter' do
12
- get('/increment').body.should =~ /Value is: 1/
13
- get('/increment').body.should =~ /Value is: 2/
14
- get('/increment').body.should =~ /Value is: 3/
14
+ session do |mock|
15
+ mock.get('/increment').should =~ /Value is: 1/
16
+ mock.get('/increment').should =~ /Value is: 2/
17
+ mock.get('/increment').should =~ /Value is: 3/
18
+ end
15
19
  end
16
20
 
17
21
  it 'decrements the counter' do
18
- get('/decrement').body.should =~ /Value is: 2/
19
- get('/decrement').body.should =~ /Value is: 1/
20
- get('/decrement').body.should =~ /Value is: 0/
22
+ session do |mock|
23
+ mock.get('/decrement').should =~ /Value is: -1/
24
+ mock.get('/decrement').should =~ /Value is: -2/
25
+ mock.get('/decrement').should =~ /Value is: -3/
26
+ end
21
27
  end
22
28
  end
@@ -13,7 +13,7 @@ class SpecActionLayoutMethod < SpecActionLayout
13
13
  layout('method_layout')
14
14
 
15
15
  def method_layout
16
- '<pre>#{ @content }</pre>'
16
+ "<pre><%= @content %></pre>"
17
17
  end
18
18
 
19
19
  def index
@@ -0,0 +1 @@
1
+ <p><%= @content %></p>
@@ -38,25 +38,25 @@ end
38
38
  describe Innate::Helper::Aspect do
39
39
  behaves_like :mock
40
40
 
41
- it 'executes before aspect' do
41
+ should 'execute before aspect' do
42
42
  $aspect_spec_before = 0
43
43
  get('/with_before').body.should == '42'
44
44
  $aspect_spec_before.should == 42
45
45
  end
46
46
 
47
- it 'executes after asepct' do
47
+ should 'execute after asepct' do
48
48
  $aspect_spec_after = 0
49
49
  get('/with_after').body.should == '2'
50
50
  $aspect_spec_after.should == 42
51
51
  end
52
52
 
53
- it 'executes wrap aspects' do
53
+ should 'execute wrap aspects' do
54
54
  $aspect_spec_wrap = 0
55
55
  get('/with_wrap').body.should == '22'
56
56
  $aspect_spec_wrap == 42
57
57
  end
58
58
 
59
- it 'calls before_all and after_all' do
59
+ should 'before_all and after_all' do
60
60
  $aspect_spec_before_all = $aspect_spec_after_all = 0
61
61
  get('/all/before_first').body.should == '42'
62
62
  $aspect_spec_before_all.should == 42
@@ -66,10 +66,10 @@ describe Innate::Helper::Aspect do
66
66
  $aspect_spec_after_all.should == 80
67
67
  end
68
68
 
69
- it 'makes instance variables in blocks available to view/method' do
69
+ should 'instance variables in blocks available to view/method' do
70
70
  get('/with_instance_var').body.should == 'Hello World'
71
71
  get('/all/with_instance_var_first').body.should == 'Hello World'
72
72
  get('/all/with_instance_var_second').body.should == 'Hello to the World'
73
- get('/without_method/aspect_hello').body.should == "Hello World!"
73
+ get('/without_method/aspect_hello').body.should == "Hello World!\n"
74
74
  end
75
75
  end
@@ -57,62 +57,81 @@ class SpecFlashSub < SpecFlash
57
57
  end
58
58
 
59
59
  describe Innate::Helper::Flash do
60
- behaves_like :mock
60
+ behaves_like :session
61
61
 
62
62
  should 'set and forget flash twice' do
63
- get('/welcome').body.should == 'Welcome manveru'
64
- get('/bye').body.should == 'Bye manveru'
65
- get('/bye').body.should == 'Bye'
63
+ session do |mock|
64
+ mock.get('/welcome').body.should == 'Welcome manveru'
65
+ mock.get('/bye').body.should == 'Bye manveru'
66
+ mock.get('/bye').body.should == 'Bye '
66
67
 
67
- get('/welcome').body.should == 'Welcome manveru'
68
- get('/bye').body.should == 'Bye manveru'
69
- get('/bye').body.should == 'Bye'
68
+ mock.get('/welcome').body.should == 'Welcome manveru'
69
+ mock.get('/bye').body.should == 'Bye manveru'
70
+ mock.get('/bye').body.should == 'Bye '
71
+ end
70
72
  end
71
73
 
72
74
  should 'work over multiple nodes' do
73
- get('/welcome').body.should == 'Welcome manveru'
74
- get('/sub/bye').body.should == 'Bye manveru'
75
- get('/sub/bye').body.should == 'Bye'
75
+ session do |mock|
76
+ mock.get('/welcome').body.should == 'Welcome manveru'
77
+ mock.get('/sub/bye').body.should == 'Bye manveru'
78
+ mock.get('/sub/bye').body.should == 'Bye '
76
79
 
77
- get('/sub/welcome').body.should == 'Welcome manveru'
78
- get('/bye').body.should == 'Bye manveru'
79
- get('/bye').body.should == 'Bye'
80
+ mock.get('/sub/welcome').body.should == 'Welcome manveru'
81
+ mock.get('/bye').body.should == 'Bye manveru'
82
+ mock.get('/bye').body.should == 'Bye '
83
+ end
80
84
  end
81
85
 
82
86
  should 'check if flash is empty' do
83
- get('/welcome').body.should == 'Welcome manveru'
84
- get('/check_empty').body.should == 'false'
85
- get('/check_empty').body.should == 'true'
87
+ session do |mock|
88
+ mock.get('/welcome').body.should == 'Welcome manveru'
89
+ mock.get('/check_empty').body.should == 'false'
90
+ mock.get('/check_empty').body.should == 'true'
91
+ end
86
92
  end
87
93
 
88
94
  should 'set and delete key within one request' do
89
- get('/set_delete_key').body.should == ''
95
+ session do |mock|
96
+ mock.get('/set_delete_key').body.should == ''
97
+ end
90
98
  end
91
99
 
92
100
  should 'set and delete key over two request' do
93
- get('/welcome').body.should == 'Welcome manveru'
94
- get('/delete_key').body.should == 'Bye'
101
+ session do |mock|
102
+ mock.get('/welcome').body.should == 'Welcome manveru'
103
+ mock.get('/delete_key').body.should == 'Bye '
104
+ end
95
105
  end
96
106
 
97
107
  should 'merge with hash' do
98
- get('/merge').body.should == {:name => 'feagliir'}.inspect
99
- get('/bye').body.should == 'Bye'
108
+ session do |mock|
109
+ mock.get('/merge').body.should == {:name => 'feagliir'}.inspect
110
+ mock.get('/bye').body.should == 'Bye '
111
+ end
100
112
  end
101
113
 
102
114
  should 'merge! with hash' do
103
- get('/merge!').body.should == {:name => 'feagliir'}.inspect
104
- get('/bye').body.should == 'Bye feagliir'
115
+ session do |mock|
116
+ mock.get('/merge!').body.should == {:name => 'feagliir'}.inspect
117
+ mock.get('/bye').body.should == 'Bye feagliir'
118
+ end
105
119
  end
106
120
 
107
121
  should 'inspect combined' do
108
- get('/welcome')
109
- get('/inspect').body.should == {:name => 'manveru', :yes => :yeah}.inspect
122
+ session do |mock|
123
+ mock.get('/welcome')
124
+ mock.get('/inspect').body.
125
+ should == {:name => 'manveru', :yes => :yeah}.inspect
126
+ end
110
127
  end
111
128
 
112
129
  should 'iterate over combined' do
113
- get('/welcome')
130
+ session do |mock|
131
+ mock.get('/welcome')
114
132
 
115
- hash = {:yes => :yeah, :name => 'manveru'}
116
- Hash[*eval(get('/iterate').body).flatten].should == hash
133
+ hash = {:yes => :yeah, :name => 'manveru'}
134
+ Hash[*eval(mock.get('/iterate').body).flatten].should == hash
135
+ end
117
136
  end
118
137
  end
@@ -56,14 +56,6 @@ describe Innate::Helper::Link do
56
56
  Two.route(:foo, :bar).should == URI('/two/foo/bar')
57
57
  end
58
58
 
59
- should 'respond with URI for node with path /foo/bar+baz' do
60
- One.route('/foo/bar+baz').should == URI('/foo/bar+baz')
61
- One.route(:foo, 'bar baz').should == URI('/foo/bar+baz')
62
-
63
- Two.route('/foo/bar+baz').should == URI('/two/foo/bar+baz')
64
- Two.route(:foo, 'bar baz').should == URI('/two/foo/bar+baz')
65
- end
66
-
67
59
  should 'respond with URI for node with GET params' do
68
60
  One.route('/', :a => :b).should == URI('/?a=b')
69
61
 
@@ -0,0 +1,101 @@
1
+ require 'spec/helper'
2
+
3
+ class SpecHelperPartial
4
+ Innate.node '/'
5
+ map_views '/'
6
+
7
+ def index
8
+ '<html><head><title><%= render_partial("/title") %></title></head></html>'
9
+ end
10
+
11
+ def title
12
+ "Title"
13
+ end
14
+
15
+ def with_params
16
+ '<html><head><title><%= render_partial("/message", :msg => "hello") %></title></head></html>'
17
+ end
18
+
19
+ def message
20
+ "Message: #{request[:msg]}"
21
+ end
22
+
23
+ def without_ext
24
+ render_template('partial')
25
+ end
26
+
27
+ def with_real_ext
28
+ render_template('partial.erb')
29
+ end
30
+
31
+ def with_needed_ext
32
+ render_template('partial.html')
33
+ end
34
+
35
+ def composed
36
+ @here = 'there'
37
+ 'From Action | ' << render_template("partial")
38
+ end
39
+
40
+ def recursive
41
+ @n ||= 1
42
+ end
43
+
44
+ def with_variable
45
+ here = 'there'
46
+ render_template("partial", :here => here)
47
+ end
48
+ end
49
+
50
+ class SpecHelperPartialWithLayout < SpecHelperPartial
51
+ Innate.node '/with_layout'
52
+ layout('layout')
53
+
54
+ def layout
55
+ '<h1>with layout</h1><%= @content %>'
56
+ end
57
+ end
58
+
59
+ describe Innate::Helper::Partial do
60
+ behaves_like :mock
61
+
62
+ should 'render partials' do
63
+ get('/').body.should == '<html><head><title>Title</title></head></html>'
64
+ end
65
+
66
+ should 'render partials with params' do
67
+ get('/with_params').body.should == '<html><head><title>Message: hello</title></head></html>'
68
+ end
69
+
70
+ should 'be able to render a template in the current scope' do
71
+ get('/composed').body.strip.should == "From Action | From Partial there"
72
+ end
73
+
74
+ should 'not require file extension' do
75
+ get('/without_ext').body.should == "From Partial \n"
76
+ end
77
+
78
+ it "the real extension will just be stripped" do
79
+ got = get('/with_real_ext').body.should == "From Partial \n"
80
+ end
81
+
82
+ it "works with the content representation instead" do
83
+ get('/with_needed_ext').body.should == "From Partial \n"
84
+ end
85
+
86
+ should 'render_template in a loop' do
87
+ get('/loop').body.gsub(/\s/,'').should == '12345'
88
+ end
89
+
90
+ should 'work recursively' do
91
+ get('/recursive').body.gsub(/\s/,'').should == '{1{2{3{44}4}3}2}'
92
+ end
93
+
94
+ should 'render template with layout' do
95
+ get('/with_layout/without_ext').body.should == "<h1>with layout</h1>From Partial \n"
96
+ end
97
+
98
+ it 'makes passed variables available in the template as instance variables' do
99
+ get('/with_variable').body.should == "From Partial there\n"
100
+ end
101
+ end