camping 2.1.532 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +72 -53
  3. data/Rakefile +25 -20
  4. data/bin/camping +1 -0
  5. data/book/01_introduction.md +6 -6
  6. data/book/02_getting_started.md +348 -267
  7. data/book/03_more_about_controllers.md +124 -0
  8. data/book/04_more_about_views.md +118 -0
  9. data/book/05_more_about_markaby.md +173 -0
  10. data/book/06_more_about_models.md +58 -0
  11. data/book/06_rules_of_thumb.md +143 -0
  12. data/book/07_philosophy.md +23 -0
  13. data/book/08_publishing_an_app.md +118 -0
  14. data/book/09_upgrade_notes.md +96 -0
  15. data/book/10_middleware.md +69 -0
  16. data/book/11_gear.md +50 -0
  17. data/examples/blog.rb +38 -38
  18. data/lib/camping/ar.rb +20 -5
  19. data/lib/camping/commands.rb +388 -0
  20. data/lib/camping/gear/filters.rb +48 -0
  21. data/lib/camping/gear/inspection.rb +32 -0
  22. data/lib/camping/gear/kuddly.rb +178 -0
  23. data/lib/camping/gear/nancy.rb +170 -0
  24. data/lib/camping/loads.rb +15 -0
  25. data/lib/camping/mab.rb +1 -1
  26. data/lib/camping/reloader.rb +22 -17
  27. data/lib/camping/server.rb +145 -70
  28. data/lib/camping/session.rb +8 -5
  29. data/lib/camping/template.rb +1 -2
  30. data/lib/camping/tools.rb +43 -0
  31. data/lib/camping/version.rb +6 -0
  32. data/lib/camping-unabridged.rb +360 -133
  33. data/lib/camping.rb +78 -47
  34. data/lib/campingtrip.md +341 -0
  35. data/test/app_camping_gear.rb +121 -0
  36. data/test/app_camping_tools.rb +1 -0
  37. data/test/app_config.rb +30 -0
  38. data/test/app_cookies.rb +1 -1
  39. data/test/app_file.rb +3 -3
  40. data/test/app_goes_meta.rb +23 -0
  41. data/test/app_inception.rb +39 -0
  42. data/test/app_markup.rb +5 -20
  43. data/test/app_migrations.rb +16 -0
  44. data/test/app_partials.rb +1 -1
  45. data/test/app_prefixed.rb +88 -0
  46. data/test/app_reloader.rb +1 -2
  47. data/test/app_route_generating.rb +69 -2
  48. data/test/app_sessions.rb +24 -2
  49. data/test/app_simple.rb +18 -18
  50. data/test/apps/migrations.rb +82 -82
  51. data/test/apps/misc.rb +1 -1
  52. data/test/gear/gear_nancy.rb +129 -0
  53. data/test/test_helper.rb +69 -12
  54. metadata +152 -92
  55. data/CHANGELOG +0 -145
  56. data/book/51_upgrading.md +0 -110
@@ -0,0 +1,23 @@
1
+ require 'test_helper'
2
+ require 'camping'
3
+
4
+ Camping.goes :Goesmeta
5
+
6
+ class Goesmeta::Test < TestCase
7
+
8
+ def test_meta_data
9
+ options = Goesmeta.options
10
+ meta = value = options[:_meta]
11
+ value = "nil" if meta == nil
12
+ assert meta != nil, "meta data was not added. #{value}"
13
+ assert meta[:file].include?("/camping/camping/test/app_goes_meta.rb"), "Wait a minute. This app Goesmeta, has a wonky creation location. #{meta[:file]}"
14
+ assert meta[:line_number] == 4, "App creation location line number is wrong. It's supposed to be 4."
15
+ end
16
+
17
+ def test_has_keys_set
18
+ opt = Goesmeta.options[:_meta]
19
+ assert opt.has_key?(:file), "app file was not set in Camping.goes. #{opt}"
20
+ assert opt.has_key?(:parent), "parent app was not set in Camping.goes. #{opt}"
21
+ end
22
+
23
+ end
@@ -0,0 +1,39 @@
1
+ require 'test_helper'
2
+ require 'camping'
3
+ require 'camping/commands'
4
+
5
+ Camping.goes :Inception
6
+ # Inception.goes :Leonardo
7
+ # Leonardo.goes :Donatello
8
+
9
+ class Inception::Test < TestCase
10
+ def the_app
11
+ app = Camping::Apps.select{|a| a.name == "Inception" }.first
12
+ app.make_camp
13
+ app
14
+ end
15
+
16
+ # def the_child
17
+ # app = Inception::Apps.select{|a| a.name == "Leonardo" }.first
18
+ # app.make_camp
19
+ # app
20
+ # end
21
+ #
22
+ # def the_brother
23
+ # app = Leonardo::Apps.select{|a| a.name == "Donatello" }.first
24
+ # app.make_camp
25
+ # app
26
+ # end
27
+
28
+ # Test that the S is pretty big in the app.
29
+ # def test_has_big_s
30
+ # s = the_app::S
31
+ # c = the_child::S
32
+ # b = the_brother::S
33
+ # # assert (s.length == c.length), "This S is the wrong length. parent: #{s.length}, child: #{c.length}."
34
+ # assert (c.length == b.length), "This S is the wrong length. child: #{c.length}, brother: #{b.length}."
35
+ # end
36
+
37
+ # Test that a Gsubbed S is equivalent.
38
+
39
+ end
data/test/app_markup.rb CHANGED
@@ -9,7 +9,7 @@ module Markup::Controllers
9
9
  render :index
10
10
  end
11
11
  end
12
-
12
+
13
13
  class NoLayout
14
14
  def get
15
15
  render :index, :layout => false
@@ -47,14 +47,14 @@ module Markup::Views
47
47
  def index
48
48
  h1 "Welcome!"
49
49
  end
50
-
50
+
51
51
  def layout
52
52
  self << '<!DOCTYPE html>'
53
53
  html do
54
54
  head do
55
55
  title "Web Page"
56
56
  end
57
-
57
+
58
58
  body { yield }
59
59
  end
60
60
  end
@@ -67,11 +67,11 @@ class Markup::Test < TestCase
67
67
  assert_body %r{<h1>Welcome!</h1>}
68
68
  assert_body %r{<title>Web Page</title>}
69
69
  end
70
-
70
+
71
71
  def test_no_layout
72
72
  get '/no/layout'
73
73
  assert_body %r{<h1>Welcome!</h1>}
74
-
74
+
75
75
  assert_reverse do
76
76
  assert_body %r{<title>Web Page</title>}
77
77
  end
@@ -82,21 +82,6 @@ class Markup::Test < TestCase
82
82
  assert_body '<img src="/mount/hello.png">'
83
83
  end
84
84
 
85
- def test_compat
86
- warning = "xhtml_strict is no longer supported (or an active standard); using HTML5 instead\n"
87
-
88
- assert_output '', warning * 3 do
89
- get '/compat/xhtml_strict'
90
- assert_body '<!DOCTYPE html><html><body><h1>Nice</h1></body></html>'
91
-
92
- get '/compat/xhtml_transitional'
93
- assert_body '<!DOCTYPE html><html><body><h1>Nice</h1></body></html>'
94
-
95
- get '/compat/xhtml_frameset'
96
- assert_body '<!DOCTYPE html><html><body><h1>Nice</h1></body></html>'
97
- end
98
- end
99
-
100
85
  def test_compat_helpers
101
86
  get '/compat/helpers'
102
87
  assert_body '/compat/helpers'
@@ -0,0 +1,16 @@
1
+ require 'test_helper'
2
+
3
+ begin
4
+ # load File.expand_path('../apps/migrations.rb', __FILE__)
5
+
6
+ # ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
7
+
8
+ # class Migrations::Test < TestCase
9
+ # def test_create
10
+ # Migrations.create
11
+ # end
12
+ # end
13
+ rescue MissingLibrary
14
+ warn "Skipping migration tests"
15
+ end
16
+
data/test/app_partials.rb CHANGED
@@ -90,7 +90,7 @@ class Partials::Test < TestCase
90
90
  assert_body "<body><p>Partial</p></body>"
91
91
  end
92
92
 
93
- def test_netsted
93
+ def test_nested
94
94
  get '/nested'
95
95
  assert_body "<body><h1>Nested</h1><p>Regular</p></body>"
96
96
  end
@@ -0,0 +1,88 @@
1
+ require 'test_helper'
2
+ require 'camping'
3
+
4
+ Camping.goes :Prefixed
5
+
6
+
7
+ module Prefixed
8
+ set :url_prefix, "pages"
9
+ end
10
+
11
+ module Prefixed::Helpers
12
+ def frontpage
13
+ R(Index)
14
+ end
15
+
16
+ def current_user
17
+ User.new
18
+ end
19
+ end
20
+
21
+ module Prefixed::Models
22
+ class User
23
+ def name
24
+ 'Bob'
25
+ end
26
+ end
27
+ end
28
+
29
+ module Prefixed::Controllers
30
+ class Index
31
+ def get
32
+ URL('/').to_s
33
+ end
34
+ end
35
+
36
+ class Friends
37
+ def get
38
+ self / "/view/1" #=> "/pages/view/1"
39
+ end
40
+ end
41
+
42
+ class Helpy
43
+ def get
44
+ @url_prefix
45
+ end
46
+ end
47
+
48
+ class Model
49
+ def get
50
+ current_user.name
51
+ end
52
+ end
53
+
54
+ class Users
55
+ def get
56
+ frontpage
57
+ end
58
+ end
59
+ end
60
+
61
+ class Prefixed::Test < TestCase
62
+
63
+ def test_url_helper_use_prefix
64
+ get '/pages/model'
65
+ assert_body "Bob"
66
+ end
67
+
68
+ def test_slash_helper_use_prefix
69
+ get '/pages/friends'
70
+ assert_body "/pages/view/1"
71
+ end
72
+
73
+ def test_prefix_ivar
74
+ get '/pages/helpy'
75
+ assert_body "pages/"
76
+ end
77
+
78
+ # Test that R(Index) produces "/pages/"
79
+ def test_r_helper_use_prefix
80
+ get '/pages/users'
81
+ assert_body "/pages"
82
+ end
83
+
84
+ def test_controller_routes_use_prefix
85
+ get '/pages', {}, 'PATH_INFO' => '/pages'
86
+ assert_body "http://example.org/pages/"
87
+ end
88
+ end
data/test/app_reloader.rb CHANGED
@@ -37,7 +37,7 @@ class TestReloader < TestCase
37
37
  def test_counter
38
38
  assert_equal 1, $counter
39
39
  end
40
-
40
+
41
41
  def test_forced_reload
42
42
  reloader.reload!
43
43
  assert_equal 2, $counter
@@ -67,4 +67,3 @@ class TestConfigRu < TestReloader
67
67
  assert_equal Reloader, reloader.apps[:reloader]
68
68
  end
69
69
  end
70
-
@@ -1,22 +1,89 @@
1
1
  require 'test_helper'
2
2
  require 'camping'
3
+ require 'camping/commands'
3
4
 
4
5
  Camping.goes :Routes
5
6
 
6
7
  module Routes::Controllers
7
- class Index
8
+ class Index < R '/'
8
9
  def get
9
10
  R(Style)
10
11
  end
11
12
  end
12
-
13
+
13
14
  class Style < R '/style\.css'
14
15
  end
16
+
17
+ class PageX
18
+ def get
19
+ end
20
+
21
+ def post
22
+ end
23
+ end
24
+
25
+ class Edit < Camper
26
+ def get
27
+ end
28
+
29
+ def post
30
+ end
31
+ end
32
+
33
+ class Post < R Edit, '/post', '/post/post'
34
+ def get
35
+ end
36
+
37
+ def post
38
+ end
39
+ end
40
+
41
+ class Bump < Edit
42
+ def get
43
+ end
44
+ end
45
+
15
46
  end
16
47
 
17
48
  class Routes::Test < TestCase
49
+ def the_app
50
+ app = Camping::Apps.select{|a| a.name == "Routes" }.first
51
+ app.make_camp
52
+ app
53
+ end
54
+
18
55
  def test_backslash
19
56
  get '/'
20
57
  assert_body '/style.css'
21
58
  end
59
+
60
+ # Test that we can get the actual controllers that we want.
61
+ def test_controllers
62
+ controllers = the_app::X.all
63
+ assert controllers.count == 6, "how many controllers are there? #{controllers.count}"
64
+ end
65
+
66
+ def test_naked_controller
67
+ controllers = the_app::X.all
68
+ assert((controllers.include? "PageX" ), "PageX is not an included controller. #{controllers}")
69
+ controller = the_app::X.const_get :PageX
70
+ assert((controller.urls == ["/page/([^/]+)"]), "PageX Controller's Routes are not right. #{controller.urls}")
71
+ end
72
+
73
+ def test_inherited_controller_not_getting_its_parents_urls
74
+ controller = the_app::X.const_get :Post
75
+ assert_equal ["/post", "/post/post"], controller.urls, "Post Controller's urls are not right. #{controller.urls}"
76
+ second_controller = the_app::X.const_get :Bump
77
+ assert_equal ["/bump"], second_controller.urls, "Bump Controller's urls are not right. #{second_controller.urls}"
78
+ end
79
+
80
+ def test_routes_helper
81
+ collection = Camping::Commands.routes((Camping::Apps.select{|a| a.name == "Routes" }.first), true)
82
+ routes = collection.routes.map(&:to_s)
83
+ assert_equal 10, routes.count, "Routes are not numbered correctly. #{routes}"
84
+ assert (routes.include? "PageX: get: /page/([^/]+) - /page/:string"), "Routes do not include: [PageX: get: /page/([^/]+) - /page/:string], #{routes}"
85
+ assert (routes.include? "PageX: post: /page/([^/]+) - /page/:string"), "Routes do not include: [PageX: post: /page/([^/]+) - /page/:string], #{routes}"
86
+ assert (routes.include? "Index: get: / - /"), "Routes do not include: [Index: get: / - /], #{routes}"
87
+ end
88
+
22
89
  end
data/test/app_sessions.rb CHANGED
@@ -16,14 +16,14 @@ module Sessions::Controllers
16
16
  redirect R(Two)
17
17
  end
18
18
  end
19
-
19
+
20
20
  class Two
21
21
  def get
22
22
  @state.two = 56
23
23
  redirect R(Three)
24
24
  end
25
25
  end
26
-
26
+
27
27
  class Three
28
28
  def get
29
29
  @state.three = 99
@@ -39,4 +39,26 @@ class Sessions::Test < TestCase
39
39
  follow_redirect!
40
40
  assert_body "[42, 56, 99]"
41
41
  end
42
+
43
+ def test_secret_length
44
+ app.set :secret, "whateverloser"
45
+ begin
46
+ app.include Camping::Session
47
+ rescue InsecureSecret => e
48
+ message = "You're Session Secret is too short. Minimum length is 64."
49
+ assert_equal(e.message, message, "You're session secret wasn't long enough.")
50
+ end
51
+
52
+ e = "empty"
53
+ message = "empty"
54
+ begin
55
+ app.set :secret, "whateverloserwhateverloserwhateverloserwhateverloserwhateverloser"
56
+ app.include Camping::Session
57
+ rescue InsecureSecret => e
58
+ message = e
59
+ end
60
+
61
+ assert_equal(e, message, "You're session secret wasn't long enough.")
62
+ end
42
63
  end
64
+
data/test/app_simple.rb CHANGED
@@ -8,40 +8,40 @@ module Simple::Controllers
8
8
  def get
9
9
  "Hello World!"
10
10
  end
11
-
11
+
12
12
  def post
13
13
  "Hello Post!"
14
14
  end
15
-
15
+
16
16
  def custom
17
17
  "Hello Custom!"
18
18
  end
19
19
  end
20
-
20
+
21
21
  class PostN
22
22
  def get(id)
23
23
  "Post ##{id}"
24
24
  end
25
25
  end
26
-
26
+
27
27
  class MultipleComplexX
28
28
  def get(str)
29
29
  "Complex: #{str}"
30
30
  end
31
31
  end
32
-
32
+
33
33
  class DateNNN
34
34
  def get(year, month, day)
35
35
  [year, month, day] * "-"
36
36
  end
37
37
  end
38
-
38
+
39
39
  class Regexp < R '/ohmy/([a-f]+)'
40
40
  def get(value)
41
41
  value
42
42
  end
43
43
  end
44
-
44
+
45
45
  class Optional < R '/optional', '/optional/([^/]+)'
46
46
  def get(value = "default")
47
47
  "Optional: #{value}"
@@ -59,45 +59,45 @@ class Simple::Test < TestCase
59
59
  def test_index
60
60
  get '/'
61
61
  assert_body "Hello World!"
62
- assert_equal "text/html", last_response.headers['Content-Type']
63
-
62
+ assert_equal "text/html", last_response.headers['content-type']
63
+
64
64
  post '/'
65
65
  assert_body "Hello Post!"
66
66
  end
67
-
67
+
68
68
  def test_post
69
69
  get '/post/1'
70
70
  assert_body "Post #1"
71
-
71
+
72
72
  get '/post/2'
73
73
  assert_body "Post #2"
74
-
74
+
75
75
  get '/post/2-oh-no'
76
76
  assert_status 404
77
77
  end
78
-
78
+
79
79
  def test_complex
80
80
  get '/multiple/complex/Hello'
81
81
  assert_body "Complex: Hello"
82
82
  end
83
-
83
+
84
84
  def test_date
85
85
  get '/date/2010/04/01'
86
86
  assert_body "2010-04-01"
87
87
  end
88
-
88
+
89
89
  def test_regexp
90
90
  get '/ohmy/cafebabe'
91
91
  assert_body "cafebabe"
92
-
92
+
93
93
  get '/ohmy/CAFEBABE'
94
94
  assert_status 404
95
95
  end
96
-
96
+
97
97
  def test_optional
98
98
  get '/optional'
99
99
  assert_body "Optional: default"
100
-
100
+
101
101
  get '/optional/override'
102
102
  assert_body "Optional: override"
103
103
  end
@@ -4,92 +4,92 @@ Camping.goes :Migrations
4
4
 
5
5
  module Migrations
6
6
  module Models
7
- class BadDude < Base; end
8
- class TableCreation < V 1.0
9
- def self.up
10
- puts "FORCE THE TABLES"
11
- create_table BadDude.table_name, :force=>true do |t|
12
- t.string :name, :limit => 255
13
- t.integer :bad
14
- t.timestamps
15
- end
16
- end
17
- def self.down
18
- drop_table BadDude.table_name
19
- end
20
- end
21
- class StartingDudes < V 1.3
22
- def self.up
23
- puts "There is only one way to make sure Bruce is the baddest"
24
- BadDude.create :name => "Bruce", :bad => 1
25
- BadDude.create :name => "Bruce", :bad => 2
26
- BadDude.create :name => "Bruce", :bad => 5
27
- end
28
- def self.down
29
- BadDude.delete_by_name "Bruce"
30
- end
31
- end
32
- class WeNeedMoreDudes < V 2.7
33
- def self.up
34
- puts "Maybe a non Bruce would help our worst case scenario planning"
35
- BadDude.create :name => "Bob", :bad => 3
36
- BadDude.create :name => "Samantha", :bad => 3
37
- end
38
- def self.down
39
- BadDude.delete_by_name "Bob"
40
- BadDude.delete_by_name "Samantha"
41
- end
42
- end
43
- class NoIMeanWeNeedBadderDudes < V 3.14159
44
- def self.up
45
- puts "just in case things get ugly"
46
- sam = BadDude.find_by_name "Samantha"
47
- sam.bad = 9001
48
- sam.save
49
- end
50
- def self.down
51
- sam = BadDude.find_by_name "Samantha"
52
- sam.bad = 3
53
- sam.save
54
- end
55
- end
56
- class WaitWeShouldDoThisEarlier < V 3.11
57
- def self.up
58
- puts "for workgroups"
59
- bruce = BadDude.find_by_name "Bob"
60
- bruce.bad = 45
61
- bruce.save
62
- end
63
- def self.down
64
- bruce = BadDude.find_by_name "Bob"
65
- bruce.bad = 3
66
- bruce.save
67
- end
68
- end
7
+ class BadDude < Base; end
8
+ class TableCreation < V 1.0
9
+ def self.up
10
+ puts "FORCE THE TABLES"
11
+ create_table BadDude.table_name, :force=>true do |t|
12
+ t.string :name, :limit => 255
13
+ t.integer :bad
14
+ t.timestamps
15
+ end
16
+ end
17
+ def self.down
18
+ drop_table BadDude.table_name
19
+ end
20
+ end
21
+ class StartingDudes < V 1.3
22
+ def self.up
23
+ puts "There is only one way to make sure Bruce is the baddest"
24
+ BadDude.create :name => "Bruce", :bad => 1
25
+ BadDude.create :name => "Bruce", :bad => 2
26
+ BadDude.create :name => "Bruce", :bad => 5
27
+ end
28
+ def self.down
29
+ BadDude.delete_by_name "Bruce"
30
+ end
31
+ end
32
+ class WeNeedMoreDudes < V 2.7
33
+ def self.up
34
+ puts "Maybe a non Bruce would help our worst case scenario planning"
35
+ BadDude.create :name => "Bob", :bad => 3
36
+ BadDude.create :name => "Samantha", :bad => 3
37
+ end
38
+ def self.down
39
+ BadDude.delete_by_name "Bob"
40
+ BadDude.delete_by_name "Samantha"
41
+ end
42
+ end
43
+ class NoIMeanWeNeedBadderDudes < V 3.14159
44
+ def self.up
45
+ puts "just in case things get ugly"
46
+ sam = BadDude.find_by_name "Samantha"
47
+ sam.bad = 9001
48
+ sam.save
49
+ end
50
+ def self.down
51
+ sam = BadDude.find_by_name "Samantha"
52
+ sam.bad = 3
53
+ sam.save
54
+ end
55
+ end
56
+ class WaitWeShouldDoThisEarlier < V 3.11
57
+ def self.up
58
+ puts "for workgroups"
59
+ bruce = BadDude.find_by_name "Bob"
60
+ bruce.bad = 45
61
+ bruce.save
62
+ end
63
+ def self.down
64
+ bruce = BadDude.find_by_name "Bob"
65
+ bruce.bad = 3
66
+ bruce.save
67
+ end
68
+ end
69
69
  end
70
70
  module Controllers
71
- class Bad < R '/(\d+)?'
72
- def get enough
73
- @dudes = BadDude.all :conditions => ["bad >= ?", enough.to_i]
74
- @howbad = enough
75
- render :savethepresident
76
- end
77
- end
71
+ class Bad < R '/(\d+)?'
72
+ def get enough
73
+ @dudes = BadDude.all :conditions => ["bad >= ?", enough.to_i]
74
+ @howbad = enough
75
+ render :savethepresident
76
+ end
77
+ end
78
78
  end
79
79
  module Views
80
- def savethepresident
81
- h1.ohnoes "The President Has Been Kidnapped By #{@howbad} Ninjas!"
82
- if @dudes.empty?
83
- div "None of the dudes are bad enough to rescue him, We are doomed!"
84
- else
85
- div "Please get the following dudes:"
86
- ul.dudes do
87
- @dudes.each do |dude|
88
- li.dude dude.name
89
- end
90
- end
91
- end
92
- end
80
+ def savethepresident
81
+ h1.ohnoes "The President Has Been Kidnapped By #{@howbad} Ninjas!"
82
+ if @dudes.empty?
83
+ diveq2 "None of the dudes are bad enough to rescue him, We are doomed!"
84
+ else
85
+ div "Please get the following dudes:"
86
+ ul.dudes do
87
+ @dudes.each do |dude|
88
+ li.dude dude.name
89
+ end
90
+ end
91
+ end
92
+ end
93
93
  end
94
94
  end
95
95
  def Migrations.create
data/test/apps/misc.rb CHANGED
@@ -12,7 +12,7 @@ module Misc
12
12
  end
13
13
  class Xsendfile
14
14
  def get
15
- @headers["X-Sendfile"] = File.expand_path(__FILE__)
15
+ @headers["x-sendfile"] = File.expand_path(__FILE__)
16
16
  "You shouldn't get this text"
17
17
  end
18
18
  end