camping 2.1.532 → 3.0.0

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 (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