tennpipes-base 3.6.6

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 (101) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +20 -0
  3. data/README.rdoc +294 -0
  4. data/Rakefile +1 -0
  5. data/bin/tennpipes +8 -0
  6. data/lib/tennpipes-base.rb +196 -0
  7. data/lib/tennpipes-base/application.rb +175 -0
  8. data/lib/tennpipes-base/application/application_setup.rb +202 -0
  9. data/lib/tennpipes-base/application/authenticity_token.rb +25 -0
  10. data/lib/tennpipes-base/application/flash.rb +229 -0
  11. data/lib/tennpipes-base/application/params_protection.rb +129 -0
  12. data/lib/tennpipes-base/application/routing.rb +1002 -0
  13. data/lib/tennpipes-base/application/show_exceptions.rb +50 -0
  14. data/lib/tennpipes-base/caller.rb +53 -0
  15. data/lib/tennpipes-base/cli/adapter.rb +33 -0
  16. data/lib/tennpipes-base/cli/base.rb +105 -0
  17. data/lib/tennpipes-base/cli/console.rb +20 -0
  18. data/lib/tennpipes-base/cli/launcher.rb +103 -0
  19. data/lib/tennpipes-base/cli/rake.rb +50 -0
  20. data/lib/tennpipes-base/cli/rake_tasks.rb +72 -0
  21. data/lib/tennpipes-base/command.rb +38 -0
  22. data/lib/tennpipes-base/ext/sinatra.rb +29 -0
  23. data/lib/tennpipes-base/filter.rb +52 -0
  24. data/lib/tennpipes-base/images/404.png +0 -0
  25. data/lib/tennpipes-base/images/500.png +0 -0
  26. data/lib/tennpipes-base/loader.rb +202 -0
  27. data/lib/tennpipes-base/logger.rb +492 -0
  28. data/lib/tennpipes-base/module.rb +58 -0
  29. data/lib/tennpipes-base/mounter.rb +308 -0
  30. data/lib/tennpipes-base/path_router.rb +119 -0
  31. data/lib/tennpipes-base/path_router/compiler.rb +110 -0
  32. data/lib/tennpipes-base/path_router/error_handler.rb +8 -0
  33. data/lib/tennpipes-base/path_router/matcher.rb +123 -0
  34. data/lib/tennpipes-base/path_router/route.rb +169 -0
  35. data/lib/tennpipes-base/reloader.rb +309 -0
  36. data/lib/tennpipes-base/reloader/rack.rb +26 -0
  37. data/lib/tennpipes-base/reloader/storage.rb +55 -0
  38. data/lib/tennpipes-base/router.rb +98 -0
  39. data/lib/tennpipes-base/server.rb +119 -0
  40. data/lib/tennpipes-base/tasks.rb +21 -0
  41. data/lib/tennpipes-base/version.rb +20 -0
  42. data/lib/tennpipes-base/version.rb~ +20 -0
  43. data/test/fixtures/app_gem/Gemfile +4 -0
  44. data/test/fixtures/app_gem/app/app.rb +3 -0
  45. data/test/fixtures/app_gem/app_gem.gemspec +17 -0
  46. data/test/fixtures/app_gem/lib/app_gem.rb +7 -0
  47. data/test/fixtures/app_gem/lib/app_gem/version.rb +3 -0
  48. data/test/fixtures/apps/complex.rb +32 -0
  49. data/test/fixtures/apps/demo_app.rb +7 -0
  50. data/test/fixtures/apps/demo_demo.rb +7 -0
  51. data/test/fixtures/apps/demo_project/api/app.rb +7 -0
  52. data/test/fixtures/apps/demo_project/api/lib/api_lib.rb +3 -0
  53. data/test/fixtures/apps/demo_project/app.rb +7 -0
  54. data/test/fixtures/apps/external_apps/fake_lib.rb +1 -0
  55. data/test/fixtures/apps/external_apps/fake_root.rb +2 -0
  56. data/test/fixtures/apps/helpers/class_methods_helpers.rb +4 -0
  57. data/test/fixtures/apps/helpers/instance_methods_helpers.rb +4 -0
  58. data/test/fixtures/apps/helpers/support.rb +1 -0
  59. data/test/fixtures/apps/helpers/system_helpers.rb +8 -0
  60. data/test/fixtures/apps/kiq.rb +3 -0
  61. data/test/fixtures/apps/lib/myklass.rb +2 -0
  62. data/test/fixtures/apps/lib/myklass/mysubklass.rb +4 -0
  63. data/test/fixtures/apps/models/child.rb +2 -0
  64. data/test/fixtures/apps/models/parent.rb +5 -0
  65. data/test/fixtures/apps/mountable_apps/rack_apps.rb +15 -0
  66. data/test/fixtures/apps/mountable_apps/static.html +1 -0
  67. data/test/fixtures/apps/precompiled_app.rb +19 -0
  68. data/test/fixtures/apps/simple.rb +32 -0
  69. data/test/fixtures/apps/static.rb +10 -0
  70. data/test/fixtures/apps/system.rb +13 -0
  71. data/test/fixtures/apps/system_class_methods_demo.rb +7 -0
  72. data/test/fixtures/apps/system_instance_methods_demo.rb +7 -0
  73. data/test/fixtures/dependencies/a.rb +9 -0
  74. data/test/fixtures/dependencies/b.rb +4 -0
  75. data/test/fixtures/dependencies/c.rb +1 -0
  76. data/test/fixtures/dependencies/circular/e.rb +13 -0
  77. data/test/fixtures/dependencies/circular/f.rb +2 -0
  78. data/test/fixtures/dependencies/circular/g.rb +2 -0
  79. data/test/fixtures/dependencies/d.rb +4 -0
  80. data/test/fixtures/reloadable_apps/external/app/app.rb +6 -0
  81. data/test/fixtures/reloadable_apps/external/app/controllers/base.rb +6 -0
  82. data/test/fixtures/reloadable_apps/main/app.rb +10 -0
  83. data/test/helper.rb +30 -0
  84. data/test/test_application.rb +185 -0
  85. data/test/test_core.rb +93 -0
  86. data/test/test_csrf_protection.rb +208 -0
  87. data/test/test_dependencies.rb +57 -0
  88. data/test/test_filters.rb +389 -0
  89. data/test/test_flash.rb +168 -0
  90. data/test/test_locale.rb +21 -0
  91. data/test/test_logger.rb +295 -0
  92. data/test/test_mounter.rb +302 -0
  93. data/test/test_params_protection.rb +195 -0
  94. data/test/test_reloader_complex.rb +74 -0
  95. data/test/test_reloader_external.rb +21 -0
  96. data/test/test_reloader_simple.rb +101 -0
  97. data/test/test_reloader_system.rb +113 -0
  98. data/test/test_restful_routing.rb +33 -0
  99. data/test/test_router.rb +281 -0
  100. data/test/test_routing.rb +2328 -0
  101. metadata +301 -0
@@ -0,0 +1,168 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/helper')
2
+
3
+ describe Tennpipes::Flash do
4
+ describe 'storage' do
5
+ before do
6
+ @storage = Tennpipes::Flash::Storage.new(
7
+ :success => 'Success msg',
8
+ :error => 'Error msg',
9
+ :notice => 'Notice msg',
10
+ :custom => 'Custom msg'
11
+ )
12
+ @storage[:one] = 'One msg'
13
+ @storage[:two] = 'Two msg'
14
+ end
15
+
16
+ it 'should acts like hash' do
17
+ assert_respond_to @storage, :[]
18
+ end
19
+
20
+ it 'should know its size' do
21
+ assert_equal 4, @storage.length
22
+ assert_equal @storage.length, @storage.size
23
+ end
24
+
25
+ it 'should sweep its content' do
26
+ assert_equal 2, @storage.sweep.size
27
+ assert_empty @storage.sweep
28
+ end
29
+
30
+ it 'should discard everything' do
31
+ assert_empty @storage.discard.sweep
32
+ end
33
+
34
+ it 'should discard specified key' do
35
+ assert_equal 1, @storage.discard(:one).sweep.size
36
+ end
37
+
38
+ it 'should keep everything' do
39
+ assert_equal 2, @storage.sweep.keep.sweep.size
40
+ end
41
+
42
+ it 'should keep only specified key' do
43
+ assert_equal 1, @storage.sweep.keep(:one).sweep.size
44
+ end
45
+
46
+ it 'should not know the values you set right away' do
47
+ @storage[:foo] = 'bar'
48
+ assert_nil @storage[:foo]
49
+ end
50
+
51
+ it 'should knows the values you set next time' do
52
+ @storage[:foo] = 'bar'
53
+ @storage.sweep
54
+ assert_equal 'bar', @storage[:foo]
55
+ end
56
+
57
+ it 'should set values for now' do
58
+ @storage.now[:foo] = 'bar'
59
+ assert_equal 'bar', @storage[:foo]
60
+ end
61
+
62
+ it 'should forgets values you set only for now next time' do
63
+ @storage.now[:foo] = 'bar'
64
+ @storage.sweep
65
+ assert_nil @storage[:foo]
66
+ end
67
+ end
68
+
69
+ routes = Proc.new do
70
+ get :index do
71
+ params[:key] ? flash[params[:key].to_sym].to_s : flash.now.inspect
72
+ end
73
+
74
+ post :index do
75
+ params.each { |k,v| flash[k.to_sym] = v.to_s }
76
+ flash.next.inspect
77
+ end
78
+
79
+ get :session do
80
+ settings.sessions?.inspect
81
+ end
82
+
83
+ get :redirect do
84
+ redirect url(:index, :key => :foo), 301, :foo => 'redirected!'
85
+ end
86
+
87
+ get :success do
88
+ flash.success = 'Yup'
89
+ end
90
+
91
+ get :error do
92
+ flash.error = 'Arg'
93
+ end
94
+
95
+ get :notice do
96
+ flash.notice = 'Mmm'
97
+ end
98
+ end
99
+
100
+ describe 'tennpipes application without sessions' do
101
+ before { mock_app(&routes) }
102
+
103
+ it 'should show nothing' do
104
+ get '/'
105
+ assert_equal '{}', body
106
+ end
107
+
108
+ it 'should set a flash' do
109
+ post '/', :foo => :bar
110
+ assert_equal '{:foo=>"bar"}', body
111
+ end
112
+ end
113
+
114
+ describe 'tennpipes application with sessions' do
115
+ before do
116
+ mock_app { enable :sessions; class_eval(&routes) }
117
+ end
118
+
119
+ it 'should be sure have sessions enabled' do
120
+ assert @app.sessions
121
+ get '/session'
122
+ assert_equal 'true', body
123
+ end
124
+
125
+ it 'should show nothing' do
126
+ get '/'
127
+ assert_equal '{}', body
128
+ end
129
+
130
+ it 'should set a flash' do
131
+ post '/', :foo => :bar
132
+ assert_equal '{:foo=>"bar"}', body
133
+ end
134
+
135
+ it 'should get a flash' do
136
+ post '/', :foo => :bar
137
+ get '/', :key => :foo
138
+ assert_equal 'bar', body
139
+ post '/'
140
+ assert_equal '{}', body
141
+ end
142
+
143
+ it 'should follow redirects with flash' do
144
+ get '/redirect'
145
+ follow_redirect!
146
+ assert_equal 'redirected!', body
147
+ assert 301, status
148
+ end
149
+
150
+ it 'should set success' do
151
+ get '/success'
152
+ get '/', :key => :success
153
+ assert_equal 'Yup', body
154
+ end
155
+
156
+ it 'should set error' do
157
+ get '/error'
158
+ get '/', :key => :error
159
+ assert_equal 'Arg', body
160
+ end
161
+
162
+ it 'should set notice' do
163
+ get '/notice'
164
+ get '/', :key => :notice
165
+ assert_equal 'Mmm', body
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,21 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/helper')
2
+
3
+ describe "Locales" do
4
+ Dir[File.expand_path("../../lib/tennpipes-base/locale/*.yml", __FILE__)].each do |file|
5
+ base_original = YAML.load_file(file)
6
+ name = File.basename(file, '.yml')
7
+ it "should should have correct locale for #{name}" do
8
+ base = base_original[name]['date']['formats']
9
+ assert base['default'].present?
10
+ assert base['short'].present?
11
+ assert base['long'].present?
12
+ assert base['only_day'].present?
13
+ base = base_original[name]['date']
14
+ assert base['day_names'].present?
15
+ assert base['abbr_day_names'].present?
16
+ assert base['month_names'].present?
17
+ assert base['abbr_month_names'].present?
18
+ assert base['order'].present?
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,295 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/helper')
2
+ require 'logger'
3
+
4
+ describe "TennpipesLogger" do
5
+ before do
6
+ @save_config = Tennpipes::Logger::Config[:test].dup
7
+ Tennpipes::Logger::Config[:test][:stream] = :null
8
+ Tennpipes::Logger.setup!
9
+ end
10
+
11
+ after do
12
+ Tennpipes::Logger::Config[:test] = @save_config
13
+ Tennpipes::Logger.setup!
14
+ end
15
+
16
+ def setup_logger(options={})
17
+ @log = StringIO.new
18
+ @logger = Tennpipes::Logger.new(options.merge(:stream => @log))
19
+ end
20
+
21
+ describe 'for logger functionality' do
22
+ describe 'check stream config' do
23
+ it 'should use stdout if stream is nil' do
24
+ Tennpipes::Logger::Config[:test][:stream] = nil
25
+ Tennpipes::Logger.setup!
26
+ assert_equal $stdout, Tennpipes.logger.log
27
+ end
28
+
29
+ it 'should use StringIO as default for test' do
30
+ assert_instance_of StringIO, Tennpipes.logger.log
31
+ end
32
+
33
+ it 'should use a custom stream' do
34
+ my_stream = StringIO.new
35
+ Tennpipes::Logger::Config[:test][:stream] = my_stream
36
+ Tennpipes::Logger.setup!
37
+ assert_equal my_stream, Tennpipes.logger.log
38
+ end
39
+ end
40
+
41
+ it 'should log something' do
42
+ setup_logger(:log_level => :error)
43
+ @logger.error "You log this error?"
44
+ assert_match(/You log this error?/, @log.string)
45
+ @logger.debug "You don't log this error!"
46
+ refute_match(/You don't log this error!/, @log.string)
47
+ @logger << "Yep this can be logged"
48
+ assert_match(/Yep this can be logged/, @log.string)
49
+ end
50
+
51
+ it 'should respond to #write for Rack::CommonLogger' do
52
+ setup_logger(:log_level => :error)
53
+ @logger.error "Error message"
54
+ assert_match /Error message/, @log.string
55
+ @logger << "logged anyways"
56
+ assert_match /logged anyways/, @log.string
57
+ @logger.write "log via alias"
58
+ assert_match /log via alias/, @log.string
59
+ end
60
+
61
+ it 'should log an application' do
62
+ mock_app do
63
+ enable :logging
64
+ get("/"){ "Foo" }
65
+ end
66
+ get "/"
67
+ assert_equal "Foo", body
68
+ assert_match /GET/, Tennpipes.logger.log.string
69
+ end
70
+
71
+ it 'should log an application\'s status code' do
72
+ mock_app do
73
+ enable :logging
74
+ get("/"){ "Foo" }
75
+ end
76
+ get "/"
77
+ assert_match /\e\[1;9m200\e\[0m OK/, Tennpipes.logger.log.string
78
+ end
79
+
80
+ describe "static asset logging" do
81
+ it 'should not log static assets by default' do
82
+ mock_app do
83
+ enable :logging
84
+ get("/images/something.png"){ env["sinatra.static_file"] = '/public/images/something.png'; "Foo" }
85
+ end
86
+ get "/images/something.png"
87
+ assert_equal "Foo", body
88
+ assert_match "", Tennpipes.logger.log.string
89
+ end
90
+
91
+ it 'should allow turning on static assets logging' do
92
+ Tennpipes.logger.instance_eval{ @log_static = true }
93
+ mock_app do
94
+ enable :logging
95
+ get("/images/something.png"){ env["sinatra.static_file"] = '/public/images/something.png'; "Foo" }
96
+ end
97
+ get "/images/something.png"
98
+ assert_equal "Foo", body
99
+ assert_match /GET/, Tennpipes.logger.log.string
100
+ Tennpipes.logger.instance_eval{ @log_static = false }
101
+ end
102
+ end
103
+
104
+ describe "health-check requests logging" do
105
+ def access_to_mock_app
106
+ mock_app do
107
+ enable :logging
108
+ get("/"){ "Foo" }
109
+ end
110
+ get "/"
111
+ end
112
+
113
+ it 'should output under debug level' do
114
+ Tennpipes.logger.instance_eval{ @level = Tennpipes::Logger::Levels[:debug] }
115
+ access_to_mock_app
116
+ assert_match /\e\[0;36m DEBUG\e\[0m/, Tennpipes.logger.log.string
117
+
118
+ Tennpipes.logger.instance_eval{ @level = Tennpipes::Logger::Levels[:devel] }
119
+ access_to_mock_app
120
+ assert_match /\e\[0;36m DEBUG\e\[0m/, Tennpipes.logger.log.string
121
+ end
122
+
123
+ it 'should not output over debug level' do
124
+ Tennpipes.logger.instance_eval{ @level = Tennpipes::Logger::Levels[:info] }
125
+ access_to_mock_app
126
+ assert_equal '', Tennpipes.logger.log.string
127
+
128
+ Tennpipes.logger.instance_eval{ @level = Tennpipes::Logger::Levels[:error] }
129
+ access_to_mock_app
130
+ assert_equal '', Tennpipes.logger.log.string
131
+ end
132
+ end
133
+ end
134
+ end
135
+
136
+ describe "alternate logger" do
137
+ class FancyLogger
138
+ attr_accessor :level, :log
139
+ def initialize(buf)
140
+ self.log = buf
141
+ self.level = 0
142
+ end
143
+ def add(level, text)
144
+ self.log << text
145
+ end
146
+ end
147
+
148
+ before do
149
+ @save_logger = Tennpipes.logger
150
+ @log = StringIO.new
151
+ Tennpipes.logger = FancyLogger.new(@log)
152
+ end
153
+
154
+ after do
155
+ Tennpipes.logger = @save_logger
156
+ end
157
+
158
+ it 'should annotate the logger to support additional Tennpipes fancyness' do
159
+ Tennpipes.logger.debug("Debug message")
160
+ assert_match(/Debug message/, @log.string)
161
+ Tennpipes.logger.exception(Exception.new 'scary message')
162
+ assert_match(/Exception - scary message/, @log.string)
163
+ end
164
+
165
+ it 'should colorize log output after colorize! is called' do
166
+ Tennpipes.logger.colorize!
167
+
168
+ mock_app do
169
+ enable :logging
170
+ get("/"){ "Foo" }
171
+ end
172
+ get "/"
173
+
174
+ assert_match /\e\[1;9m200\e\[0m OK/, @log.string
175
+ end
176
+ end
177
+
178
+ describe "alternate logger: stdlib logger" do
179
+ before do
180
+ @log = StringIO.new
181
+ @save_logger = Tennpipes.logger
182
+ Tennpipes.logger = Logger.new(@log)
183
+ end
184
+
185
+ after do
186
+ Tennpipes.logger = @save_logger
187
+ end
188
+
189
+ it 'should annotate the logger to support additional Tennpipes fancyness' do
190
+ Tennpipes.logger.debug("Debug message")
191
+ assert_match(/Debug message/, @log.string)
192
+ end
193
+
194
+ it 'should colorize log output after colorize! is called' do
195
+ Tennpipes.logger.colorize!
196
+
197
+ mock_app do
198
+ enable :logging
199
+ get("/"){ "Foo" }
200
+ end
201
+ get "/"
202
+
203
+ assert_match /\e\[1;9m200\e\[0m OK/, @log.string
204
+ end
205
+ end
206
+
207
+ describe "options :colorize_logging" do
208
+ def access_to_mock_app
209
+ mock_app do
210
+ enable :logging
211
+ get("/"){ "Foo" }
212
+ end
213
+ get "/"
214
+ end
215
+
216
+ before do
217
+ @save_config = Tennpipes::Logger::Config[:test].dup
218
+ end
219
+
220
+ after do
221
+ Tennpipes::Logger::Config[:test] = @save_config
222
+ Tennpipes::Logger.setup!
223
+ end
224
+
225
+ describe 'default' do
226
+ before do
227
+ Tennpipes::Logger::Config[:test][:colorize_logging] = true
228
+ Tennpipes::Logger.setup!
229
+ end
230
+
231
+ it 'should use colorize logging' do
232
+ Tennpipes::Logger.setup!
233
+
234
+ access_to_mock_app
235
+ assert_match /\e\[1;9m200\e\[0m OK/, Tennpipes.logger.log.string
236
+ end
237
+ end
238
+
239
+ describe 'set value is false' do
240
+ before do
241
+ Tennpipes::Logger::Config[:test][:colorize_logging] = false
242
+ Tennpipes::Logger.setup!
243
+ end
244
+
245
+ it 'should not use colorize logging' do
246
+ access_to_mock_app
247
+ assert_match /200 OK/, Tennpipes.logger.log.string
248
+ end
249
+ end
250
+ end
251
+
252
+ describe "options :source_location" do
253
+ before do
254
+ Tennpipes::Logger::Config[:test][:source_location] = true
255
+ Tennpipes::Logger.setup!
256
+ end
257
+
258
+ def stub_root(base_path = File.expand_path("."), &block)
259
+ callable = proc{ |*args| File.join(base_path, *args) }
260
+ Tennpipes.stub(:root, callable, &block)
261
+ end
262
+
263
+ it 'should output source_location if :source_location is set to true' do
264
+ stub_root { Tennpipes.logger.debug("hello world") }
265
+ assert_match /\[test\/test_logger\.rb:264\] hello world/, Tennpipes.logger.log.string
266
+ end
267
+
268
+ it 'should output source_location if file path is relative' do
269
+ stub_message = "test/test_logger.rb:269:in `test'"
270
+ Tennpipes::Logger.logger.stub(:caller, [stub_message]){ stub_root { Tennpipes.logger.debug("hello relative path") }}
271
+ assert_match /\[test\/test_logger\.rb:269\] hello relative path/, Tennpipes.logger.log.string
272
+ end
273
+
274
+ it 'should not output source_location if :source_location is set to false' do
275
+ Tennpipes::Logger::Config[:test][:source_location] = false
276
+ Tennpipes::Logger.setup!
277
+ stub_root { Tennpipes.logger.debug("hello world") }
278
+ assert_match /hello world/, Tennpipes.logger.log.string
279
+ refute_match /\[.+?\] hello world/, Tennpipes.logger.log.string
280
+ end
281
+
282
+ it 'should not output source_location unless file path is not started with Tennpipes.root' do
283
+ stub_root("/unknown/path/") { Tennpipes.logger.debug("hello boy") }
284
+ assert_match /hello boy/, Tennpipes.logger.log.string
285
+ refute_match /\[.+?\] hello boy/, Tennpipes.logger.log.string
286
+ end
287
+
288
+ it 'should not output source_location if source file path is started with Tennpipes.root + vendor' do
289
+ base_path = File.expand_path(File.dirname(__FILE__) + '/fixtures/')
290
+ stub_message = File.expand_path(File.dirname(__FILE__) + '/fixtures/vendor/logger.rb') + ":291:in `test'"
291
+ Tennpipes::Logger.logger.stub(:caller, [stub_message]) { stub_root(base_path) { Tennpipes.logger.debug("hello vendor") } }
292
+ assert_match /hello vendor/, Tennpipes.logger.log.string
293
+ refute_match /\[.+?\] hello vendor/, Tennpipes.logger.log.string
294
+ end
295
+ end