manveru-innate 2009.04.08 → 2009.04.18

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,6 +3,8 @@ module Innate
3
3
 
4
4
  # Used by caches that serialize their contents to the filesystem.
5
5
  module FileBased
6
+ attr_reader :filename
7
+
6
8
  def cache_setup(*args)
7
9
  @prefix = args.compact.join('-')
8
10
 
@@ -152,10 +152,10 @@ module Innate
152
152
  # helper :foo_bar # => FooBar
153
153
  # helper :foo # => Foo
154
154
  def get(name)
155
- name = name.to_s.split('_').map{|e| e.capitalize}.join
155
+ module_name = /^#{name.to_s.dup.delete('_')}$/i
156
156
 
157
157
  options.namespaces.each do |namespace|
158
- found = namespace.constants.grep(/^#{name}$/i).first
158
+ found = namespace.constants.grep(module_name).first
159
159
  return namespace.const_get(found) if found
160
160
  end
161
161
 
@@ -28,12 +28,12 @@ module Innate
28
28
  hashes, names = args.partition{|arg| arg.respond_to?(:merge!) }
29
29
  hashes.each{|to_merge| hash.merge!(to_merge) }
30
30
 
31
+ escape = Rack::Utils.method(:escape)
31
32
  location = route_location(self)
32
- front = Array[location, name, *names].join('/').squeeze('/')
33
+ front = Array[location, name, *names.map{|n| escape[n]}].join('/').squeeze('/')
33
34
 
34
35
  return URI(front) if hash.empty?
35
36
 
36
- escape = Rack::Utils.method(:escape)
37
37
  query = hash.map{|k, v| "#{escape[k]}=#{escape[v]}" }.join(';')
38
38
  URI("#{front}?#{query}")
39
39
  end
@@ -61,7 +61,9 @@ module Innate
61
61
  end
62
62
 
63
63
  def render_custom(action_name, variables = {})
64
- action = resolve(action_name.to_s)
64
+ unless action = resolve(action_name.to_s)
65
+ raise(ArgumentError, "No Action %p on #{self}" % action_name)
66
+ end
65
67
 
66
68
  action.sync_variables(self.action)
67
69
  action.instance = action.node.new
@@ -3,12 +3,20 @@ module Innate
3
3
  module SendFile
4
4
  # Not optimally performing but convenient way to send files by their
5
5
  # filename.
6
- def send_file(filename, content_type = nil)
6
+ #
7
+ # I think we should remove this from the default helpers and move it into
8
+ # Ramaze, the functionality is almost never used, the naming is ambigous,
9
+ # and it doesn't use the send_file capabilities of frontend servers.
10
+ #
11
+ # So for now, I'll mark it for deprecation
12
+ def send_file(filename, content_type = nil, content_disposition = nil)
7
13
  content_type ||= Rack::Mime.mime_type(::File.extname(filename))
14
+ content_disposition ||= File.basename(filename)
8
15
 
9
16
  response.body = ::File.readlines(filename, 'rb')
10
17
  response['Content-Length'] = ::File.size(filename).to_s
11
18
  response['Content-Type'] = content_type
19
+ response['Content-Disposition'] = content_disposition
12
20
  response.status = 200
13
21
 
14
22
  throw(:respond, response)
@@ -813,9 +813,7 @@ module Innate
813
813
  when /^(.*)\.(.*)\.(.*)$/
814
814
  action_name, wish_ext, engine_ext = $1, $2, $3
815
815
  when /^(.*)\.(.*)$/
816
- action_name, wish_ext, engine_ext = $1, 'html', $2
817
- when /.*/
818
- p $1
816
+ action_name, wish_ext, engine_ext = $1, wish, $2
819
817
  end
820
818
 
821
819
  mapping[wish_ext] ||= {}
@@ -1,9 +1,4 @@
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
-
7
2
  class Response < Rack::Response
8
3
  include Optioned
9
4
 
@@ -12,8 +7,6 @@ module Innate
12
7
  :headers, {'Content-Type' => 'text/html'}
13
8
  end
14
9
 
15
- attr_accessor :length
16
-
17
10
  def reset
18
11
  self.status = 200
19
12
  self.header.delete('Content-Type')
@@ -62,8 +62,7 @@ module Innate
62
62
  end
63
63
 
64
64
  def flush(response = @response)
65
- return unless @cache_sid
66
- return if @cache_sid.empty?
65
+ return if !@cache_sid or @cache_sid.empty?
67
66
 
68
67
  flash.rotate!
69
68
  ttl = (Time.at(cookie_value[:expires]) - Time.now).to_i
@@ -1,10 +1,10 @@
1
+ begin; require 'rubygems'; rescue LoadError; end
2
+
1
3
  require 'bacon'
4
+ require 'rack/test'
5
+ require(File.expand_path("#{__FILE__}/../")) unless defined?(Innate)
2
6
 
3
7
  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,50 +15,9 @@ 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
-
39
18
  shared :mock do
40
19
  Innate.setup_dependencies
20
+ extend Rack::Test::Methods
41
21
 
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
- { 'CONTENT_TYPE' => "multipart/form-data; boundary=#{boundary}",
61
- 'CONTENT_LENGTH' => Rack::Utils.bytesize(body).to_s,
62
- :input => StringIO.new(body) }
63
- end
22
+ def app; Innate.middleware; end
64
23
  end
@@ -1,3 +1,3 @@
1
1
  module Innate
2
- VERSION = "2009.04.08"
2
+ VERSION = "2009.04.18"
3
3
  end
@@ -0,0 +1,30 @@
1
+ require 'spec/helper'
2
+ require 'example/app/retro_games'
3
+
4
+ describe 'Retro-games app' do
5
+ behaves_like :mock
6
+
7
+ it 'lists the first game' do
8
+ get '/'
9
+ last_response.should =~ /1 =&gt; Pacman/
10
+ end
11
+
12
+ it 'has a form to add another game' do
13
+ get '/'
14
+ last_response.should =~ /<form/
15
+ end
16
+
17
+ it 'allows you to add another game' do
18
+ post '/create', :name => 'Street Fighter II'
19
+ follow_redirect!
20
+ last_response.should =~ /0 =&gt; Street Fighter II/
21
+ end
22
+
23
+ it 'allows you to vote for a game' do
24
+ get '/vote/Street+Fighter+II'
25
+ follow_redirect!
26
+ last_response.should =~ /1 =&gt; Street Fighter II/
27
+ end
28
+
29
+ FileUtils.rm_f('games.yaml')
30
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec/helper'
2
+ require 'example/provides'
3
+
4
+ describe 'examples/provide' do
5
+ behaves_like :mock
6
+
7
+ it 'provides YAML representation' do
8
+ get '/list.yaml'
9
+ last_response.body.should == ARTICLES.to_yaml
10
+ last_response['Content-Type'].should == 'text/yaml'
11
+
12
+ get '/list'
13
+ last_response.body.should == ''
14
+ last_response['Content-Type'].should == 'text/html'
15
+ end
16
+ end
@@ -2,27 +2,21 @@ require 'spec/helper'
2
2
  require 'example/session'
3
3
 
4
4
  describe 'example/session' do
5
- behaves_like :session
5
+ behaves_like :mock
6
6
 
7
7
  it 'starts at 0' do
8
- session do |mock|
9
- mock.get('/').should =~ /Value is: 0/
10
- end
8
+ get('/').body.should =~ /Value is: 0/
11
9
  end
12
10
 
13
11
  it 'increments the counter' do
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
12
+ get('/increment').body.should =~ /Value is: 1/
13
+ get('/increment').body.should =~ /Value is: 2/
14
+ get('/increment').body.should =~ /Value is: 3/
19
15
  end
20
16
 
21
17
  it 'decrements the counter' do
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
18
+ get('/decrement').body.should =~ /Value is: 2/
19
+ get('/decrement').body.should =~ /Value is: 1/
20
+ get('/decrement').body.should =~ /Value is: 0/
27
21
  end
28
22
  end
@@ -57,81 +57,62 @@ class SpecFlashSub < SpecFlash
57
57
  end
58
58
 
59
59
  describe Innate::Helper::Flash do
60
- behaves_like :session
60
+ behaves_like :mock
61
61
 
62
62
  should 'set and forget flash twice' do
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'
63
+ get('/welcome').body.should == 'Welcome manveru'
64
+ get('/bye').body.should == 'Bye manveru'
65
+ get('/bye').body.should == 'Bye'
67
66
 
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
67
+ get('/welcome').body.should == 'Welcome manveru'
68
+ get('/bye').body.should == 'Bye manveru'
69
+ get('/bye').body.should == 'Bye'
72
70
  end
73
71
 
74
72
  should 'work over multiple nodes' do
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'
73
+ get('/welcome').body.should == 'Welcome manveru'
74
+ get('/sub/bye').body.should == 'Bye manveru'
75
+ get('/sub/bye').body.should == 'Bye'
79
76
 
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
77
+ get('/sub/welcome').body.should == 'Welcome manveru'
78
+ get('/bye').body.should == 'Bye manveru'
79
+ get('/bye').body.should == 'Bye'
84
80
  end
85
81
 
86
82
  should 'check if flash is empty' do
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
83
+ get('/welcome').body.should == 'Welcome manveru'
84
+ get('/check_empty').body.should == 'false'
85
+ get('/check_empty').body.should == 'true'
92
86
  end
93
87
 
94
88
  should 'set and delete key within one request' do
95
- session do |mock|
96
- mock.get('/set_delete_key').body.should == ''
97
- end
89
+ get('/set_delete_key').body.should == ''
98
90
  end
99
91
 
100
92
  should 'set and delete key over two request' do
101
- session do |mock|
102
- mock.get('/welcome').body.should == 'Welcome manveru'
103
- mock.get('/delete_key').body.should == 'Bye'
104
- end
93
+ get('/welcome').body.should == 'Welcome manveru'
94
+ get('/delete_key').body.should == 'Bye'
105
95
  end
106
96
 
107
97
  should 'merge with hash' do
108
- session do |mock|
109
- mock.get('/merge').body.should == {:name => 'feagliir'}.inspect
110
- mock.get('/bye').body.should == 'Bye'
111
- end
98
+ get('/merge').body.should == {:name => 'feagliir'}.inspect
99
+ get('/bye').body.should == 'Bye'
112
100
  end
113
101
 
114
102
  should 'merge! with hash' do
115
- session do |mock|
116
- mock.get('/merge!').body.should == {:name => 'feagliir'}.inspect
117
- mock.get('/bye').body.should == 'Bye feagliir'
118
- end
103
+ get('/merge!').body.should == {:name => 'feagliir'}.inspect
104
+ get('/bye').body.should == 'Bye feagliir'
119
105
  end
120
106
 
121
107
  should 'inspect combined' do
122
- session do |mock|
123
- mock.get('/welcome')
124
- mock.get('/inspect').body.
125
- should == {:name => 'manveru', :yes => :yeah}.inspect
126
- end
108
+ get('/welcome')
109
+ get('/inspect').body.should == {:name => 'manveru', :yes => :yeah}.inspect
127
110
  end
128
111
 
129
112
  should 'iterate over combined' do
130
- session do |mock|
131
- mock.get('/welcome')
113
+ get('/welcome')
132
114
 
133
- hash = {:yes => :yeah, :name => 'manveru'}
134
- Hash[*eval(mock.get('/iterate').body).flatten].should == hash
135
- end
115
+ hash = {:yes => :yeah, :name => 'manveru'}
116
+ Hash[*eval(get('/iterate').body).flatten].should == hash
136
117
  end
137
118
  end
@@ -56,6 +56,14 @@ 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
+
59
67
  should 'respond with URI for node with GET params' do
60
68
  One.route('/', :a => :b).should == URI('/?a=b')
61
69
 
@@ -20,7 +20,7 @@ class SpecRedirectHelper
20
20
  end
21
21
 
22
22
  def redirect_referer_action
23
- redirect_referer
23
+ redirect_referer(r(:noop))
24
24
  end
25
25
 
26
26
  def no_actual_redirect
@@ -69,77 +69,92 @@ describe Innate::Helper::Redirect do
69
69
  end
70
70
 
71
71
  should 'redirect' do
72
- got = get("#@uri/redirection")
73
- got.status.should == 302
74
- got.headers['Location'].should == "#@uri/index"
75
- got.headers['Content-Type'].should == "text/html"
72
+ get("#@uri/redirection")
73
+
74
+ last_response.status.should == 302
75
+ last_response.headers['Location'].should == "#@uri/index"
76
+ last_response.headers['Content-Type'].should == "text/html"
76
77
  end
77
78
 
78
79
  should 'redirect twice' do
79
- got = get("#@uri/double_redirection")
80
- got.status.should == 302
81
- got.headers['Location'].should == "#@uri/redirection"
82
- got.headers['Content-Type'].should == "text/html"
80
+ get("#@uri/double_redirection")
81
+
82
+ last_response.status.should == 302
83
+ last_response.headers['Location'].should == "#@uri/redirection"
84
+ last_response.headers['Content-Type'].should == "text/html"
83
85
  end
84
86
 
85
87
  should 'redirect to referer' do
86
- got = get("#@uri/redirect_referer_action", 'HTTP_REFERER' => '/noop')
87
- got.status.should == 302
88
- got.headers['Location'].should == "#@uri/noop"
89
- got.headers['Content-Type'].should == "text/html"
90
- got = get("#@uri/redirect_referer_action", 'HTTP_REFERER' => "#@uri/redirect_referer_action")
91
- got.status.should == 302
92
- got.headers['Location'].should == "#@uri/"
93
- got.headers['Content-Type'].should == "text/html"
88
+ header 'HTTP_REFERER', '/index'
89
+ get("#@uri/redirect_referer_action")
90
+
91
+ last_response.status.should == 302
92
+ last_response.headers['Location'].should == "#@uri/index"
93
+ last_response.headers['Content-Type'].should == "text/html"
94
+ end
95
+
96
+ should 'redirect to fallback if referrer is identical' do
97
+ header 'HTTP_REFERER', "#@uri/redirect_referer_action"
98
+ get("#@uri/redirect_referer_action")
99
+
100
+ last_response.status.should == 302
101
+ last_response.headers['Location'].should == "#@uri/noop"
102
+ last_response.headers['Content-Type'].should == "text/html"
94
103
  end
95
104
 
96
105
  should 'use #r' do
97
- got = get("#@uri/redirect_method")
98
- got.status.should == 302
99
- got.headers['Location'].should == "#@uri/noop"
100
- got.headers['Content-Type'].should == "text/html"
106
+ get("#@uri/redirect_method")
107
+
108
+ last_response.status.should == 302
109
+ last_response.headers['Location'].should == "#@uri/noop"
110
+ last_response.headers['Content-Type'].should == "text/html"
101
111
  end
102
112
 
103
113
  should 'work with absolute uris' do
104
- got = get("#@uri/absolute_redirect")
105
- got.status.should == 302
106
- got.headers['Location'].should == "#@uri/noop"
107
- got.headers['Content-Type'].should == "text/html"
114
+ get("#@uri/absolute_redirect")
115
+
116
+ last_response.status.should == 302
117
+ last_response.headers['Location'].should == "#@uri/noop"
118
+ last_response.headers['Content-Type'].should == "text/html"
108
119
  end
109
120
 
110
121
  should 'support #respond' do
111
- got = get("#@uri/loop")
112
- got.status.should == 200
113
- got.body.should == 'no loop'
122
+ get("#@uri/loop")
123
+
124
+ last_response.status.should == 200
125
+ last_response.body.should == 'no loop'
114
126
  end
115
127
 
116
128
  should 'support #respond with status' do
117
- got = get("#@uri/respond_with_status")
118
- got.status.should == 404
119
- got.body.should == 'not found'
129
+ get("#@uri/respond_with_status")
130
+
131
+ last_response.status.should == 404
132
+ last_response.body.should == 'not found'
120
133
  end
121
134
 
122
135
  should 'support #respond!' do
123
- got = get("#@uri/destructive_respond")
124
- got.status.should == 200
125
- got.body.should == 'destructive'
136
+ get("#@uri/destructive_respond")
137
+
138
+ last_response.status.should == 200
139
+ last_response.body.should == 'destructive'
126
140
  end
127
141
 
128
142
  should 'redirect without modifying the target' do
129
- got = get("#@uri/redirect_unmodified")
130
- got.status.should == 302
131
- got.headers['Location'].should == '/noop'
143
+ get("#@uri/redirect_unmodified")
144
+
145
+ last_response.status.should == 302
146
+ last_response.headers['Location'].should == '/noop'
132
147
  end
133
148
 
134
149
  should 'catch redirection' do
135
- got = get("#@uri/no_actual_redirect")
136
- got.status.should == 200
137
- got.body.should == 'no actual redirect'
150
+ get("#@uri/no_actual_redirect")
151
+ last_response.status.should == 200
152
+ last_response.body.should == 'no actual redirect'
138
153
  end
139
154
 
140
155
  should 'catch double redirect' do
141
- got = get("#@uri/no_actual_double_redirect")
142
- got.status.should == 200
143
- got.body.should == 'no actual double redirect'
156
+ get("#@uri/no_actual_double_redirect")
157
+ last_response.status.should == 200
158
+ last_response.body.should == 'no actual double redirect'
144
159
  end
145
160
  end