tennpipes-base 3.6.6

Sign up to get free protection for your applications and to get access to all the features.
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,7 @@
1
+ TENNPIPES_ROOT = File.dirname(__FILE__) unless defined? TENNPIPES_ROOT
2
+
3
+ module Demo
4
+ class Demo < Tennpipes::Application
5
+ set :reload, true
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module DemoProject
2
+ class API
3
+ def self.call(_)
4
+ [200, {}, ["api app"]]
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module DemoProject
2
+ APILib = Class.new
3
+ end
@@ -0,0 +1,7 @@
1
+ module DemoProject
2
+ class App < Tennpipes::Application
3
+ get :index do
4
+ "tennpipes app"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1 @@
1
+ FakeLib = 1
@@ -0,0 +1,2 @@
1
+ class FakeRoot < Sinatra::Base
2
+ end
@@ -0,0 +1,4 @@
1
+ begin
2
+ require '/tmp/tennpipes_class_demo'
3
+ rescue LoadError
4
+ end
@@ -0,0 +1,4 @@
1
+ begin
2
+ require '/tmp/tennpipes_instance_demo'
3
+ rescue LoadError
4
+ end
@@ -0,0 +1 @@
1
+ require 'active_support/logger_silence'
@@ -0,0 +1,8 @@
1
+ require 'resolv'
2
+
3
+ SystemDemo.helpers do
4
+ def resolv
5
+ Resolv.name
6
+ end
7
+ end
8
+
@@ -0,0 +1,3 @@
1
+ class Kiq < ::Sinatra::Base
2
+ set :root, '/weird'
3
+ end
@@ -0,0 +1,2 @@
1
+ class MyKlass < OpenStruct
2
+ end
@@ -0,0 +1,4 @@
1
+ class MyKlass
2
+ class MySubKlass
3
+ end
4
+ end
@@ -0,0 +1,2 @@
1
+ class Child < Parent
2
+ end
@@ -0,0 +1,5 @@
1
+ class Parent
2
+ def family
3
+ 'Danes'
4
+ end
5
+ end
@@ -0,0 +1,15 @@
1
+
2
+ class RackApp
3
+ def self.call(_)
4
+ [200, {}, ["hello rack app"]]
5
+ end
6
+ end
7
+
8
+ RackApp2 = lambda{|_| [200, {}, ["hello rack app2"]] }
9
+
10
+ class SinatraApp < Sinatra::Base
11
+ set :public_folder, File.dirname(__FILE__)
12
+ get "/" do
13
+ "hello sinatra app"
14
+ end
15
+ end
@@ -0,0 +1 @@
1
+ hello static file
@@ -0,0 +1,19 @@
1
+ TENNPIPES_ROOT = File.dirname(__FILE__) unless defined? TENNPIPES_ROOT
2
+
3
+ Tennpipes.configure_apps do
4
+ set :precompile_routes, true
5
+ end
6
+
7
+ module PrecompiledApp
8
+ class App < Tennpipes::Application
9
+ 10.times{|n| get("/#{n}"){} }
10
+ end
11
+ class SubApp < Tennpipes::Application
12
+ 10.times{|n| get("/#{n}"){} }
13
+ end
14
+ end
15
+
16
+ Tennpipes.mount("PrecompiledApp::SubApp").to("/subapp")
17
+ Tennpipes.mount("PrecompiledApp::App").to("/")
18
+
19
+ Tennpipes.load!
@@ -0,0 +1,32 @@
1
+ TENNPIPES_ROOT = File.dirname(__FILE__) unless defined? TENNPIPES_ROOT
2
+ # Remove this comment if you want do some like this: ruby RACK_ENV=test app.rb
3
+ #
4
+ # require 'tennpipes-base'
5
+ #
6
+
7
+ class SimpleDemo < Tennpipes::Application
8
+ set :reload, true
9
+ before { true }
10
+ after { true }
11
+ error(404) { "404" }
12
+ end
13
+
14
+ SimpleDemo.controllers do
15
+ get "/" do
16
+ 'The magick number is: 2767356926488785838763860464013972991031534522105386787489885890443740254365!' # Change only the number!!!
17
+ end
18
+
19
+ get "/rand" do
20
+ rand(2 ** 256).to_s
21
+ end
22
+ end
23
+
24
+ ## If you want use this as a standalone app uncomment:
25
+ #
26
+ # Tennpipes.mount("SimpleDemo").to("/")
27
+ # Tennpipes.run! unless Tennpipes.loaded? # If you enable reloader prevent to re-run the app
28
+ #
29
+ # Then run it from your console: ruby -I"lib" test/fixtures/apps/simple.rb
30
+ #
31
+
32
+ Tennpipes.load!
@@ -0,0 +1,10 @@
1
+ TENNPIPES_ROOT = File.dirname(__FILE__) unless defined? TENNPIPES_ROOT
2
+
3
+ class StaticDemo < Tennpipes::Application
4
+ disable :reload
5
+ def self.reload!
6
+ fail 'reload! called'
7
+ end
8
+ end
9
+
10
+ Tennpipes.load!
@@ -0,0 +1,13 @@
1
+ TENNPIPES_ROOT = File.dirname(__FILE__) unless defined? TENNPIPES_ROOT
2
+
3
+ class SystemDemo < Tennpipes::Application
4
+ set :reload, true
5
+ end
6
+
7
+ SystemDemo.controllers do
8
+ get '/' do
9
+ resolv
10
+ end
11
+ end
12
+
13
+ Tennpipes.load!
@@ -0,0 +1,7 @@
1
+ TENNPIPES_ROOT = File.dirname(__FILE__) unless defined? TENNPIPES_ROOT
2
+
3
+ class SystemClassMethodsDemo < Tennpipes::Application
4
+ set :reload, true
5
+ end
6
+
7
+ Tennpipes.load!
@@ -0,0 +1,7 @@
1
+ TENNPIPES_ROOT = File.dirname(__FILE__) unless defined? TENNPIPES_ROOT
2
+
3
+ class SystemInstanceMethodsDemo < Tennpipes::Application
4
+ set :reload, true
5
+ end
6
+
7
+ Tennpipes.load!
@@ -0,0 +1,9 @@
1
+ # This file will be safe loaded three times.
2
+ # The first one fail because B and C constant are not defined
3
+ # The second one file because B requires C constant so will not be loaded
4
+ # The third one B and C are defined
5
+
6
+ # But here we need some of b.rb
7
+ A_result = [B, C]
8
+
9
+ A = "A"
@@ -0,0 +1,4 @@
1
+ # But here we need some of c.rb and a.rb
2
+ B_result = C
3
+
4
+ B = "B"
@@ -0,0 +1 @@
1
+ C = "C"
@@ -0,0 +1,13 @@
1
+ class E
2
+ def self.fields
3
+ @fields ||= []
4
+ end
5
+
6
+ def self.inherited(subclass)
7
+ subclass.fields.replace fields.dup
8
+ end
9
+
10
+ G
11
+
12
+ fields << "name"
13
+ end
@@ -0,0 +1,2 @@
1
+ class F < E
2
+ end
@@ -0,0 +1,2 @@
1
+ class G
2
+ end
@@ -0,0 +1,4 @@
1
+ D = 0 unless defined?(D)
2
+ D += 1
3
+
4
+ raise "SomeThing"
@@ -0,0 +1,6 @@
1
+
2
+ module ReloadableApp
3
+ class External < Tennpipes::Application
4
+ set :reload, true
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+
2
+ ReloadableApp::External.controller :base do
3
+ get :index do
4
+ "Hello External App"
5
+ end
6
+ end
@@ -0,0 +1,10 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../external/app/app')
2
+
3
+ module ReloadableApp
4
+ class Main < Tennpipes::Application
5
+ set :reload, true
6
+ get :index do
7
+ "hey"
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,30 @@
1
+ ENV['RACK_ENV'] = 'test'
2
+ TENNPIPES_ROOT = File.dirname(__FILE__) unless defined?(TENNPIPES_ROOT)
3
+
4
+ require 'minitest/autorun'
5
+ require 'minitest/pride'
6
+ require 'i18n'
7
+ require 'json'
8
+ require 'builder'
9
+ require 'rack/test'
10
+ require 'yaml'
11
+ require 'tennpipes-base'
12
+
13
+ require 'ext/minitest-spec'
14
+ require 'ext/rack-test-methods'
15
+ require 'ext/rack-test-utils'
16
+
17
+ class MiniTest::Spec
18
+ include Rack::Test::Methods
19
+
20
+ # Sets up a Sinatra::Base subclass defined with the block
21
+ # given. Used in setup or individual spec methods to establish
22
+ # the application.
23
+ def mock_app(base=Tennpipes::Application, &block)
24
+ @app = Sinatra.new(base, &block)
25
+ end
26
+
27
+ def app
28
+ Rack::Lint.new(@app)
29
+ end
30
+ end
@@ -0,0 +1,185 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/helper')
2
+ require 'haml'
3
+
4
+ class TennpipesPristine < Tennpipes::Application; end
5
+ class TennpipesTestApp < Tennpipes::Application; end
6
+ class TennpipesTestApp2 < Tennpipes::Application; end
7
+
8
+ describe "Application" do
9
+ before { Tennpipes.clear! }
10
+
11
+ describe 'for application functionality' do
12
+
13
+ it 'should check default options' do
14
+ assert File.identical?(__FILE__, TennpipesPristine.app_file)
15
+ assert_equal :tennpipes_pristine, TennpipesPristine.app_name
16
+ assert_equal :test, TennpipesPristine.environment
17
+ assert_equal Tennpipes.root('views'), TennpipesPristine.views
18
+ assert TennpipesPristine.raise_errors
19
+ assert !TennpipesPristine.logging
20
+ assert !TennpipesPristine.sessions
21
+ assert !TennpipesPristine.dump_errors
22
+ assert !TennpipesPristine.show_exceptions
23
+ assert TennpipesPristine.raise_errors
24
+ assert !Tennpipes.configure_apps
25
+ end
26
+
27
+ it 'should check tennpipes specific options' do
28
+ assert !TennpipesPristine.instance_variable_get(:@_configured)
29
+ TennpipesPristine.send(:setup_application!)
30
+ assert_equal :tennpipes_pristine, TennpipesPristine.app_name
31
+ assert_equal 'StandardFormBuilder', TennpipesPristine.default_builder
32
+ assert TennpipesPristine.instance_variable_get(:@_configured)
33
+ assert !TennpipesPristine.reload?
34
+ end
35
+
36
+ it 'should set global project settings' do
37
+ Tennpipes.configure_apps { enable :sessions; set :foo, "bar" }
38
+ TennpipesTestApp.send(:default_configuration!)
39
+ TennpipesTestApp2.send(:default_configuration!)
40
+ assert TennpipesTestApp.sessions, "should have sessions enabled"
41
+ assert_equal "bar", TennpipesTestApp.settings.foo, "should have foo assigned"
42
+ assert_equal TennpipesTestApp.session_secret, TennpipesTestApp2.session_secret
43
+ end
44
+
45
+ it 'should be able to configure_apps multiple times' do
46
+ Tennpipes.configure_apps { set :foo1, "bar" }
47
+ Tennpipes.configure_apps { set :foo1, "bam" }
48
+ Tennpipes.configure_apps { set :foo2, "baz" }
49
+ TennpipesTestApp.send(:default_configuration!)
50
+ assert_equal "bam", TennpipesTestApp.settings.foo1, "should have foo1 assigned to bam"
51
+ assert_equal "baz", TennpipesTestApp.settings.foo2, "should have foo2 assigned to baz"
52
+ end
53
+
54
+ it 'should have shared sessions accessible in project' do
55
+ Tennpipes.configure_apps { enable :sessions; set :session_secret, 'secret' }
56
+ Tennpipes.mount("TennpipesTestApp").to("/write")
57
+ Tennpipes.mount("TennpipesTestApp2").to("/read")
58
+ TennpipesTestApp.send :default_configuration!
59
+ TennpipesTestApp.get('/') { session[:foo] = "shared" }
60
+ TennpipesTestApp2.send(:default_configuration!)
61
+ TennpipesTestApp2.get('/') { session[:foo] }
62
+ @app = Tennpipes.application
63
+ get '/write'
64
+ get '/read'
65
+ assert_equal 'shared', body
66
+ end
67
+
68
+ it 'should be able to execute the register keyword inside the configure_apps block' do
69
+ Asdf = Module.new
70
+ Tennpipes.configure_apps { register Asdf }
71
+ class GodFather < Tennpipes::Application; end
72
+ assert_includes GodFather.extensions, Asdf
73
+ end
74
+
75
+ it 'should able to set custome session management' do
76
+ class TennpipesTestApp3 < Tennpipes::Application
77
+ set :sessions, :use => Rack::Session::Pool
78
+ end
79
+ Tennpipes.mount("TennpipesTestApp3").to("/")
80
+ TennpipesTestApp3.get('/write') { session[:foo] = "pool" }
81
+ TennpipesTestApp3.get('/read') { session[:foo] }
82
+ @app = Tennpipes.application
83
+ get '/write'
84
+ get '/read'
85
+ assert_equal 'pool', body
86
+ end
87
+
88
+ it 'should have different session values in different session management' do
89
+ class TennpipesTestApp4 < Tennpipes::Application
90
+ enable :sessions
91
+ end
92
+ class TennpipesTestApp5 < Tennpipes::Application
93
+ set :sessions, :use => Rack::Session::Pool
94
+ end
95
+ Tennpipes.mount("TennpipesTestApp4").to("/write")
96
+ Tennpipes.mount("TennpipesTestApp5").to("/read")
97
+ TennpipesTestApp4.get('/') { session[:foo] = "cookie" }
98
+ TennpipesTestApp5.get('/') { session[:foo] }
99
+ @app = Tennpipes.application
100
+ get '/write'
101
+ get '/read'
102
+ assert_equal '', body
103
+ end
104
+
105
+ # compare to: test_routing: allow global provides
106
+ it 'should set content_type to nil if none can be determined' do
107
+ mock_app do
108
+ provides :xml
109
+
110
+ get("/foo"){ "Foo in #{content_type.inspect}" }
111
+ get("/bar"){ "Foo in #{content_type.inspect}" }
112
+ end
113
+
114
+ get '/foo', {}, { 'HTTP_ACCEPT' => 'application/xml' }
115
+ assert_equal 'Foo in :xml', body
116
+ get '/foo'
117
+ assert_equal 'Foo in :xml', body
118
+
119
+ get '/bar', {}, { 'HTTP_ACCEPT' => 'application/xml' }
120
+ assert_equal "Foo in nil", body
121
+ end
122
+
123
+ it 'should resolve views and layouts paths' do
124
+ assert_equal Tennpipes.root('views')+'/users/index', TennpipesPristine.view_path('users/index')
125
+ assert_equal Tennpipes.root('views')+'/layouts/app', TennpipesPristine.layout_path(:app)
126
+ end
127
+
128
+ describe "errors" do
129
+ it 'should have not mapped errors on development' do
130
+ mock_app { get('/'){ 'HI' } }
131
+ get "/"
132
+ assert @app.errors.empty?
133
+ end
134
+
135
+ it 'should have mapped errors on production' do
136
+ mock_app { set :environment, :production; get('/'){ 'HI' } }
137
+ get "/"
138
+ assert_equal 1, @app.errors.size
139
+ end
140
+
141
+ it 'should overide errors' do
142
+ mock_app do
143
+ set :environment, :production
144
+ get('/'){ raise }
145
+ error(::Exception){ 'custom error' }
146
+ end
147
+ get "/"
148
+ assert_equal 1, @app.errors.size
149
+ assert_equal 'custom error', body
150
+ end
151
+
152
+ it 'should raise NameError even if Kernel.require is extended' do
153
+ assert_raises NameError do
154
+ ConstTest = Class.new(Tennpipes::Application)
155
+ require 'active_support/dependencies'
156
+ ConstTest::UninitializedConstant
157
+ end
158
+ end
159
+ end
160
+
161
+ describe "pre-compile routes" do
162
+ it "should compile routes before first request if enabled the :precompile_routes option" do
163
+ require File.expand_path(File.dirname(__FILE__) + '/fixtures/apps/precompiled_app')
164
+ assert_instance_of Tennpipes::PathRouter::Compiler, PrecompiledApp::App.compiled_router.engine
165
+ assert_instance_of Tennpipes::PathRouter::Compiler, PrecompiledApp::SubApp.compiled_router.engine
166
+ assert_equal true, PrecompiledApp::App.compiled_router.engine.compiled?
167
+ assert_equal true, PrecompiledApp::SubApp.compiled_router.engine.compiled?
168
+ assert_equal 20, PrecompiledApp::App.compiled_router.engine.regexps.length
169
+ assert_equal 20, PrecompiledApp::SubApp.compiled_router.engine.regexps.length
170
+ end
171
+ end
172
+
173
+ describe 'global prerequisites' do
174
+ after do
175
+ Tennpipes::Application.prerequisites.clear
176
+ end
177
+
178
+ it 'should be inherited by children of Tennpipes::Application' do
179
+ Tennpipes::Application.prerequisites << 'my_prerequisites'
180
+ class InheritanceTest < Tennpipes::Application; end
181
+ assert_includes InheritanceTest.prerequisites, 'my_prerequisites'
182
+ end
183
+ end
184
+ end # application functionality
185
+ end