camping 3.0.2 → 3.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6aa52530d539466610a0ae7b505a72176f38b2ba12975f776447dcfb4e6d6934
4
- data.tar.gz: 31c521e39db07c10472bff1d6e56bec41b55052bf0e40b3a8165e1266873815b
3
+ metadata.gz: afe5fa876178ba1acb276392788f76f4df3451c8b212234892565b6cd93043b0
4
+ data.tar.gz: c521c1b9e5c149474a4590efbc17fe61bd681bc79e510441bf1bd572e6505351
5
5
  SHA512:
6
- metadata.gz: 200a6af8d4e245e7bf1fac8bb5965ec9ec2a049fc2b3965b9129e5fcc296f251de7ec5fd83656bde13dac6e2869692f52dd5d707e5718e84a498da1f742f7d07
7
- data.tar.gz: b80af113694c5303ab1c955876dd6e6e0eb78d0324fa2b4d16f9361b8c8114e0af1cfdffd6761d452a22a3ee5c8febc679078ed50978a2d8a1385806d6da208b
6
+ metadata.gz: 7c77c29289f3e917c182178a3c0593f4d5b0ae3352a08fde92a4787ec6d4b98330108fe37860cf73f45896b37d32235918fafe123f674ba93088aeb1760958a3
7
+ data.tar.gz: 8b95dff758b4fb8adac1704bce9de1980c50ee25a8c1bf8492e3cbc9d847cde87b131e24329fea495ab4e4ec62925ba578f3c30a9c17b9aae7514038d57f79b7
data/README.md CHANGED
@@ -64,27 +64,38 @@ end
64
64
  ## Installation
65
65
 
66
66
  Interested yet? Luckily it's quite easy to install Camping. We'll be using
67
- a tool called RubyGems, so if you don't have that installed yet, go grab it!
68
- Once that's sorted out, open up a Terminal or Command Line and enter:
67
+ a tool called RubyGems, and Bundler, so if you don't have that installed
68
+ yet, go grab it! Once that's sorted out, open up a Terminal or Command
69
+ Line and enter:
69
70
 
70
71
  ```
71
72
  gem install camping
72
73
  ```
73
74
 
75
+ Also make certain to have Bundler installed:
76
+
77
+ ```
78
+ gem install bundler
79
+ ```
80
+
74
81
  ~~Even better, install the Camping Omnibus, a full package of recommended libs:~~ Camping Omnibus will return for summer vacation.
75
82
 
83
+ Now make a new directory filled with your camp essentials using the `camping new` command:
84
+
85
+ ```
86
+ camping new Donuts # You can replace Donuts with whatever but CamelCased.
87
+ ```
88
+
89
+ Move to your new directory, then use bundler to install all of your camp's dependencies:
90
+
76
91
  ```
77
- gem install camping-omnibus
92
+ cd donuts; bundle install
78
93
  ```
79
94
 
80
- If not, you should be aware of that Camping itself only depends on
81
- [Rack](https://github.com/rack/rack), and if you're going to use the views you also
82
- need to install **[markaby](https://github.com/markaby/markaby)**, and if you're going to use the database you need
83
- **activerecord** as well.
95
+ You can now run camping using the `camping` command. We recommend running camping in development mode locally. Make certain to prefix the camping command with `bundle exec` to run your app with the gems you've installed just for your camp:
84
96
 
85
97
  ```
86
- gem install markaby
87
- gem install activerecord
98
+ bundle exec camping -e development
88
99
  ```
89
100
 
90
101
  ## Learning
data/Rakefile CHANGED
@@ -70,6 +70,18 @@ Rake::TestTask.new(:test) do |t|
70
70
  t.test_files = FileList['test/app_*.rb', 'test/gear/gear_*.rb']
71
71
  end
72
72
 
73
+ ## Reloader Tests
74
+ Rake::TestTask.new(:reloader) do |t|
75
+ t.libs << "test"
76
+ t.test_files = FileList['test/reload_*.rb']
77
+ end
78
+
79
+ ## Reloader Tests
80
+ Rake::TestTask.new(:configreloader) do |t|
81
+ t.libs << "test"
82
+ t.test_files = FileList['test/config_*.rb']
83
+ end
84
+
73
85
  ## Diff
74
86
  desc "Compare camping and camping-unabridged"
75
87
  task :diff do
@@ -97,7 +109,7 @@ end
97
109
  error = false
98
110
 
99
111
  ## Check
100
- task :check => ["test", "check:valid", "check:equal", "check:size", "check:lines", "check:exit"]
112
+ task :check => ["test", "reloader", "configreloader", "check:valid", "check:equal", "check:size", "check:lines", "check:exit"]
101
113
  namespace :check do
102
114
 
103
115
  desc "Check source code validity"
@@ -0,0 +1,14 @@
1
+ # Campguide is a small helper to map common errors in a Camping project to a quick resolution.
2
+ module Campguide
3
+ Errors = {"wrong number of arguments (given 3, expected 0)" => "ArgumentError. This is sometimes caused when you try to send a request to a controller when a camping app hasn't made camp yet. make certain to call Camping.make_camp to set up your apps."}
4
+
5
+ class << self
6
+
7
+ # accepts string error messages and tries to match them with better explanations of the error.
8
+ def make_sense(error_message)
9
+ message = Errors[error_message]
10
+ puts message ? message : error_message
11
+ end
12
+
13
+ end
14
+ end
@@ -237,9 +237,79 @@ task :test => 'test:all'
237
237
  namespace 'test' do
238
238
  Rake::TestTask.new('all') do |t|
239
239
  t.libs << 'test'
240
- t.test_files = FileList['test/nuts_*.rb']
240
+ t.test_files = FileList['test/test_*.rb']
241
241
  end
242
242
  end
243
+ TXT
244
+ end
245
+
246
+ # writes a test_helper
247
+ def make_test_helper
248
+ write 'test/test_helper.r', <<-TXT
249
+ # Test Helper
250
+ $:.unshift File.dirname(__FILE__) + '/../'
251
+
252
+ begin
253
+ require 'rubygems'
254
+ rescue LoadError
255
+ end
256
+
257
+ require 'minitest/autorun'
258
+ require 'rack/test'
259
+ require 'minitest/reporters'
260
+ require 'minitest/hooks'
261
+ Minitest::Reporters.use! [Minitest::Reporters::DefaultReporter.new(:color => true)]
262
+
263
+ # Default TestCase with some helpers.
264
+ # The same stuff we use for Camping itself.
265
+ class TestCase < MiniTest::Test
266
+ include Rack::Test::Methods
267
+ include Minitest::Hooks
268
+
269
+ def self.inherited(mod)
270
+ mod.app = Object.const_get(mod.to_s[/\w+/])
271
+ super
272
+ end
273
+
274
+ class << self
275
+ attr_accessor :app
276
+ end
277
+
278
+ def setup
279
+ super
280
+ Camping.make_camp
281
+ end
282
+
283
+ def body() last_response.body end
284
+ def app() self.class.app end
285
+
286
+ def response_body() last_response.to_a end
287
+
288
+ def assert_reverse
289
+ begin
290
+ yield
291
+ rescue Exception
292
+ else
293
+ assert false, "Block didn't fail"
294
+ end
295
+ end
296
+
297
+ def assert_body(str, message="")
298
+ case str
299
+ when Regexp
300
+ assert_match(str, last_response.body.strip, message)
301
+ else
302
+ assert_equal(str.to_s, last_response.body.strip, message)
303
+ end
304
+ end
305
+
306
+ def assert_status(code, message="")
307
+ assert_equal(code, last_response.status, message)
308
+ end
309
+
310
+ def test_silly; end
311
+ end
312
+
243
313
  TXT
244
314
  end
245
315
 
@@ -274,6 +344,7 @@ group :test do
274
344
  gem 'minitest', '~> 5.0'
275
345
  gem 'minitest-reporters'
276
346
  gem 'rack-test'
347
+ gem 'minitest-hooks'
277
348
  end
278
349
 
279
350
  GEM
@@ -287,6 +358,8 @@ Camping is really fun and I hope you enjoy it.
287
358
 
288
359
  Start camping by running: `camping` in the root directory.
289
360
 
361
+ To start Camping in development mode run: `camping -e development
362
+
290
363
  READ
291
364
  end
292
365
 
@@ -360,47 +433,55 @@ RUBY
360
433
  end
361
434
 
362
435
  class Commands
436
+ class << self
363
437
 
364
- # A helper method to spit out Routes for an application
365
- def self.routes(theApp = Camping, silent = false)
366
- routes = Camping::CommandsHelpers::RoutesParser.parse theApp
367
- routes.display unless silent == true
368
- return routes
369
- end
438
+ # A helper method to spit out Routes for an application
439
+ def routes(theApp = Camping, silent = false)
440
+ routes = Camping::CommandsHelpers::RoutesParser.parse theApp
441
+ routes.display unless silent == true
442
+ return routes
443
+ end
370
444
 
371
- def self.new_cmd(app_name=:Camp)
372
-
373
- # Normalize the app_name
374
- Camping::CommandsHelpers.app_name_from_input(app_name) => {app_name:, snake_name:, camel_name:}
375
-
376
- # make a directory then move there.
377
- # _original_dir = Dir.pwd
378
- Dir.mkdir("#{snake_name}") unless Dir.exist?("#{snake_name}")
379
- Dir.chdir("#{snake_name}")
380
-
381
- # generate a new camping app in a directory named after it:
382
- Generators::make_camp_file(camel_name)
383
- Generators::make_gitignore()
384
- Generators::make_rakefile()
385
- Generators::make_ruby_version()
386
- Generators::make_configkdl()
387
- Generators::make_gemfile()
388
- Generators::make_readme()
389
- Generators::make_public_folder()
390
- Generators::make_test_folder()
391
-
392
- # optionally add omnibus support
393
- # add src/ folder
394
- # add lib/ folder
395
- # add views/ folder
396
-
397
- # optionally add a local database too, through guidebook
398
- # add db/ folder
399
- # add db/migrate folder
400
- # add db/config.kdl
401
- # append migrations stuff to Rakefile.
402
- `ls`
403
- end
445
+ def new_cmd(app_name=:Camp)
446
+
447
+ # Normalize the app_name
448
+ Camping::CommandsHelpers.app_name_from_input(app_name) => {app_name:, snake_name:, camel_name:}
449
+
450
+ # make a directory then move there.
451
+ # _original_dir = Dir.pwd
452
+ Dir.mkdir("#{snake_name}") unless Dir.exist?("#{snake_name}")
453
+ Dir.chdir("#{snake_name}")
454
+
455
+ # generate a new camping app in a directory named after it:
456
+ Generators::make_camp_file(camel_name)
457
+ Generators::make_gitignore()
458
+ Generators::make_rakefile()
459
+ Generators::make_ruby_version()
460
+ Generators::make_configkdl()
461
+ Generators::make_gemfile()
462
+ Generators::make_readme()
463
+ Generators::make_public_folder()
464
+ Generators::make_test_folder()
465
+ Generators::make_test_helper()
466
+
467
+ # optionally add omnibus support
468
+ # add src/ folder
469
+ # add lib/ folder
470
+ # add views/ folder
471
+
472
+ # optionally add a local database too, through guidebook
473
+ # add db/ folder
474
+ # add db/migrate folder
475
+ # add db/config.kdl
476
+ # append migrations stuff to Rakefile.
477
+ `ls`
478
+ end
479
+
480
+ # TODO: Create this generator
481
+ # generates the apps folder from apps found in camp.rb or config.ru
482
+ # def generate_apps_folder
483
+ # end
404
484
 
485
+ end
405
486
  end
406
487
  end
@@ -1,48 +1,48 @@
1
1
  # This gear is originally from filtering_camping gem by judofyr, and techarc.
2
2
  module Gear
3
- module Filters
4
- module ClassMethods
5
- def filters
6
- @_filters ||= {:before => [], :after => []}
7
- end
3
+ module Filters
4
+ module ClassMethods
5
+ def filters
6
+ @_filters ||= {:before => [], :after => []}
7
+ end
8
8
 
9
- def before(actions, &blk)
10
- actions = [actions] unless actions.is_a?(Array)
11
- actions.each do |action|
12
- filters[:before] << [action, blk]
13
- end
14
- end
9
+ def before(actions, &blk)
10
+ actions = [actions] unless actions.is_a?(Array)
11
+ actions.each do |action|
12
+ filters[:before] << [action, blk]
13
+ end
14
+ end
15
15
 
16
- def after(actions, &blk)
17
- actions = [actions] unless actions.is_a?(Array)
18
- actions.each do |action|
19
- filters[:after] << [action, blk]
20
- end
21
- end
22
- end
16
+ def after(actions, &blk)
17
+ actions = [actions] unless actions.is_a?(Array)
18
+ actions.each do |action|
19
+ filters[:after] << [action, blk]
20
+ end
21
+ end
22
+ end
23
23
 
24
- def self.included(mod)
25
- mod.extend(ClassMethods)
26
- end
24
+ def self.included(mod)
25
+ mod.extend(ClassMethods)
26
+ end
27
27
 
28
- def self.setup(app, *a, &block) end
28
+ def self.setup(app, *a, &block) end
29
29
 
30
- def run_filters(type)
31
- o = self.class.to_s.split("::")
32
- filters = Object.const_get(o.first).filters
33
- filters[type].each do |filter|
34
- if (filter[0].is_a?(Symbol) && (filter[0] == o.last.to_sym || filter[0] == :all)) ||
35
- (filter[0].is_a?(String) && /^#{filter[0]}\/?$/ =~ @env.REQUEST_URI)
36
- self.instance_eval(&filter[1])
37
- end
38
- end
39
- end
30
+ def run_filters(type)
31
+ o = self.class.to_s.split("::")
32
+ filters = Object.const_get(o.first).filters
33
+ filters[type].each do |filter|
34
+ if (filter[0].is_a?(Symbol) && (filter[0] == o.last.to_sym || filter[0] == :all)) ||
35
+ (filter[0].is_a?(String) && /^#{filter[0]}\/?$/ =~ @env.REQUEST_URI)
36
+ self.instance_eval(&filter[1])
37
+ end
38
+ end
39
+ end
40
40
 
41
- def service(*a)
42
- run_filters(:before)
43
- super(*a)
44
- run_filters(:after)
45
- self
46
- end
47
- end
41
+ def service(*a)
42
+ run_filters(:before)
43
+ super(*a)
44
+ run_filters(:after)
45
+ self
46
+ end
47
+ end
48
48
  end
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- # lib/camping/config
3
2
  # load and parse settings.
4
3
 
5
4
  begin
@@ -1,3 +1,6 @@
1
+ require 'zeitwerk'
2
+ require 'listen'
3
+
1
4
  module Camping
2
5
  # == The Camping Reloader
3
6
  #
@@ -31,18 +34,39 @@ module Camping
31
34
  # Blog and Wiki, but they will update themselves if yourapp.rb changes.
32
35
  #
33
36
  # You can also give Reloader more than one script.
34
- class Reloader
37
+ class Loader
35
38
  attr_reader :file
39
+ Loaders = []
36
40
 
37
- def initialize(file, &blk)
41
+ def initialize(file=nil, &blk)
38
42
  @file = file
39
43
  @mtime = Time.at(0)
40
44
  @requires = []
41
45
  @apps = {}
42
46
  @callback = blk
43
-
47
+ @root = Dir.pwd
48
+ @file = @root + '/camp.rb' if @file == nil
49
+ @zeit = Zeitwerk::Loader.new
50
+ Loaders << @zeit
51
+
52
+ # setup Zeit for this reloader
53
+ setup_zeit(@zeit)
54
+
55
+ # setup recursive listener on the apps and lib directories from the source script.
56
+ @listener = Listen.to("#{@root}/apps", "#{@root}/lib", "#{@root}") do |modified, added, removed|
57
+ @mtime = Time.now
58
+ reload!
59
+ end
60
+ start
44
61
  end
45
62
 
63
+ # pass through methods to the Listener.
64
+ # for testing purposes.
65
+ def processing_events?;@listener.processing? end
66
+ def stop;@listener.stop end
67
+ def pause;@listener.pause end
68
+ def start;@listener.start end
69
+
46
70
  def name
47
71
  @name ||= begin
48
72
  base = @file.dup
@@ -52,29 +76,29 @@ module Camping
52
76
  end
53
77
  end
54
78
 
55
- # Loads the apps available in this script. Use <tt>apps</tt> to get
56
- # the loaded apps.
57
- def load_apps(old_apps)
79
+ # remove_constants called inside this.
80
+ def load_everything()
58
81
  all_requires = $LOADED_FEATURES.dup
59
82
  all_apps = Camping::Apps.dup
60
83
 
61
84
  load_file
85
+ reload_directory("#{@root}/apps")
86
+ reload_directory("#{@root}/lib")
87
+ Camping.make_camp
62
88
  ensure
63
89
  @requires = []
64
- dirs = []
65
90
  new_apps = Camping::Apps - all_apps
66
91
 
67
92
  @apps = new_apps.inject({}) do |hash, app|
68
93
  if file = app.options[:__FILE__]
69
94
  full = File.expand_path(file)
70
95
  @requires << [file, full]
71
- dirs << full.sub(/\.[^.]+$/, '')
72
96
  end
73
97
 
74
98
  key = app.name.to_sym
75
99
  hash[key] = app
76
100
 
77
- if !old_apps.include?(key)
101
+ apps.each do |app|
78
102
  @callback.call(app) if @callback
79
103
  app.create if app.respond_to?(:create)
80
104
  end
@@ -84,12 +108,13 @@ module Camping
84
108
 
85
109
  ($LOADED_FEATURES - all_requires).each do |req|
86
110
  full = full_path(req)
87
- @requires << [req, full] if dirs.any? { |x| full.index(x) == 0 }
111
+ @requires << [req, full] # if dirs.any? { |x| full.index(x) == 0 }
88
112
  end
89
113
 
90
114
  @mtime = mtime
91
115
 
92
116
  self
117
+
93
118
  end
94
119
 
95
120
  # load_file
@@ -102,13 +127,15 @@ module Camping
102
127
  else
103
128
  load(@file)
104
129
  end
130
+ @requires << [@file, File.expand_path(@file)]
105
131
  end
106
132
 
107
- # Removes all the apps defined in this script.
108
- def remove_apps
109
- @requires.each do |(path, full)|
110
- $LOADED_FEATURES.delete(path)
111
- end
133
+ # removes all constants recursively included using this script as a root.
134
+ # so everything in /apps, and /lib in relation from this script.
135
+ def remove_constants
136
+ @requires.each do |(path, full)|
137
+ $LOADED_FEATURES.delete(path)
138
+ end
112
139
 
113
140
  @apps.each do |name, app|
114
141
  Camping::Apps.delete(app)
@@ -116,6 +143,7 @@ module Camping
116
143
  end.dup
117
144
  ensure
118
145
  @apps.clear
146
+ @requires.clear
119
147
  end
120
148
 
121
149
  # Reloads the file if needed. No harm is done by calling this multiple
@@ -125,8 +153,10 @@ module Camping
125
153
  reload!
126
154
  end
127
155
 
156
+ # Force a reload.
128
157
  def reload!
129
- load_apps(remove_apps)
158
+ remove_constants
159
+ load_everything
130
160
  end
131
161
 
132
162
  # Checks if both scripts watches the same file.
@@ -144,6 +174,46 @@ module Camping
144
174
 
145
175
  private
146
176
 
177
+ # sets up Zeit autoloading for the script locations.
178
+ def setup_zeit(loader)
179
+ loader.push_dir("#{@root}/apps") if can_add_directory "#{@root}/apps"
180
+ loader.push_dir("#{@root}/lib") if can_add_directory "#{@root}/lib"
181
+ loader.enable_reloading if ENV['environment'] == 'development'
182
+ loader.setup
183
+ end
184
+
185
+ # verifies that we can add a directory to the loader.
186
+ # used for testing to prevent multiple loaders from watching the same directory.
187
+ def can_add_directory(directory)
188
+ if Dir.exist?("#{@root}/apps")
189
+ Loaders.each do |loader|
190
+ return false if loader.dirs.include? directory
191
+ end
192
+ true
193
+ else
194
+ false
195
+ end
196
+ end
197
+
198
+ # Splits the descendent files and folders found in a given directory for eager loading and recursion.
199
+ def folders_and_files_in(directory)
200
+ directory = directory + "/*" # unless directory
201
+ [Dir.glob(directory).select {|f| !File.directory? f },
202
+ Dir.glob(directory).select {|f| File.directory? f }]
203
+ end
204
+
205
+ # Reloads a directory recursively. loading more shallow files before deeper files.
206
+ def reload_directory(directory)
207
+ files, folders = folders_and_files_in(directory)
208
+ files.each {|file|
209
+ @requires << [file, File.expand_path(file)]
210
+ load file
211
+ }
212
+ folders.each {|folder|
213
+ reload_directory folder
214
+ }
215
+ end
216
+
147
217
  def mtime
148
218
  @requires.map do |(path, full)|
149
219
  File.mtime(full)
data/lib/camping/loads.rb CHANGED
@@ -8,8 +8,8 @@ require 'bundler/setup'
8
8
 
9
9
  # internal dependencies
10
10
  require 'camping/tools'
11
+ require 'camping/campguide'
11
12
  require 'camping/gear/filters'
12
13
  require 'camping/gear/nancy'
13
14
  require 'camping/gear/inspection'
14
15
  require 'camping/gear/kuddly'
15
-
@@ -3,7 +3,7 @@ require 'erb'
3
3
  require 'rack'
4
4
  require 'rackup'
5
5
  require 'camping/version'
6
- require 'camping/reloader'
6
+ require 'camping/loader'
7
7
  require 'camping/commands'
8
8
 
9
9
  # == The Camping Server (for development)
@@ -128,9 +128,10 @@ module Camping
128
128
  exit
129
129
  end
130
130
 
131
+ @reloader.reload!
132
+ r = @reloader
133
+
131
134
  if options[:routes] == true
132
- @reloader.reload!
133
- r = @reloader
134
135
  eval("self", TOPLEVEL_BINDING).meta_def(:reload!) { r.reload!; nil }
135
136
  ARGV.clear
136
137
  Camping::Commands.routes
@@ -139,16 +140,11 @@ module Camping
139
140
 
140
141
  if options[:server] == "console"
141
142
  puts "** Starting console"
142
- @reloader.reload!
143
- r = @reloader
144
143
  eval("self", TOPLEVEL_BINDING).meta_def(:reload!) { r.reload!; nil }
145
144
  ARGV.clear
146
145
  IRB.start
147
146
  exit
148
147
  else
149
- @reloader.reload!
150
- r = @reloader
151
- Camping.make_camp
152
148
  name = server.name[/\w+$/]
153
149
  puts "** Starting #{name} on #{options[:Host]}:#{options[:Port]}"
154
150
  super
@@ -215,7 +211,6 @@ module Camping
215
211
  def call(env)
216
212
  if ENV['environment'] == 'development'
217
213
  @reloader.reload
218
- Camping.make_camp
219
214
  end
220
215
 
221
216
  # our switch statement iterates through possible app outcomes, no apps
@@ -1,5 +1,5 @@
1
1
  require 'rack/session'
2
- class InsecureSecret < Exception #:nodoc: all
2
+ class InsecureSecretError < Exception #:nodoc: all
3
3
  end
4
4
  module Camping
5
5
  # == Getting Started
@@ -31,7 +31,7 @@ module Camping
31
31
  def self.included(app)
32
32
  key = "#{app}.state".downcase
33
33
  secret = app.options[:secret] || ['camping-secret',__FILE__, File.mtime('Rakefile')].join(":")*2
34
- raise InsecureSecret, "You're Session Secret is too short. Minimum length is 64." if secret.length < 64
34
+ raise InsecureSecretError, "Your Session Secret is too short. Minimum length is 64." if secret.length < 64
35
35
  app.use Rack::Session::Cookie, :key => key, :secrets => secret
36
36
  end
37
37
  end
@@ -1,5 +1,5 @@
1
1
  module Camping
2
- VERSION = "3.0.2"
2
+ VERSION = "3.1.0"
3
3
  def self.version
4
4
  VERSION
5
5
  end
@@ -724,7 +724,6 @@ module Camping
724
724
  #
725
725
  # See: https://github.com/rack/rack/blob/main/SPEC.rdoc
726
726
  def call(e)
727
- make_camp # TODO: Find a better, more consistent place for setting everything up.
728
727
  k,m,*a=X.D e["PATH_INFO"],e['REQUEST_METHOD'].downcase,e
729
728
  k.new(e,m,prx).service(*a).to_a
730
729
  rescue
@@ -752,8 +751,9 @@ module Camping
752
751
  def method_missing(m, c, *a)
753
752
  h = Hash === a[-1] ? a.pop : {}
754
753
  e = H[Rack::MockRequest.env_for('',h.delete(:env)||{})]
755
- # puts "method missing failure for controller: #{c}, method: #{m} "
756
754
  k = X.const_get(c).new(e,m.to_s,prx)
755
+ # rescue => error # : wrong number of arguments
756
+ # Campguide::make_sense error.message
757
757
  h.each { |i, v| k.send("#{i}=", v) }
758
758
  k.service(*a)
759
759
  end
@@ -914,6 +914,7 @@ module Camping
914
914
  # setup caller data
915
915
  sp = caller[0].split('`')[0].split(":")
916
916
  fl, ln, pr = sp[0], sp[1].to_i, nil
917
+ # ln = 0
917
918
 
918
919
  # Create the app
919
920
  Apps << a = eval(S.gsub(/Camping/,m.to_s), g, fl, ln)
data/lib/camping.rb CHANGED
@@ -66,7 +66,7 @@ k.meta_def(:urls){[A.(k,"#{c.to_s.scan(/.[^A-Z]*/).map(&N.method(:[]))*'/'}",p)]
66
66
  .respond_to?(:urls) || mu==true)};end end;I=R()end;X=Controllers
67
67
  class<<self;def make_camp;X.M prx;Apps.map(&:make_camp) end;def routes;(Apps.map(&:routes)<<X.v).flatten end
68
68
  def prx;@_prx||=CampTools.normalize_slashes(O[:url_prefix])end
69
- def call e;make_camp;k,m,*a=X.D e["PATH_INFO"],e['REQUEST_METHOD'].
69
+ def call e;k,m,*a=X.D e["PATH_INFO"],e['REQUEST_METHOD'].
70
70
  downcase,e;k.new(e,m,prx).service(*a).to_a;rescue;r500(:I,k,m,$!,:env=>e).to_a end
71
71
  def method_missing m,c,*a;h=Hash===a[-1]?a.pop : {};e=H[Rack::MockRequest.
72
72
  env_for('',h.delete(:env)||{})];k=X.const_get(c).new(e,m.to_s,prx);h.each{|i,v|
data/test/app_config.rb CHANGED
@@ -5,16 +5,14 @@ module Config end
5
5
 
6
6
  class Config::Test < TestCase
7
7
 
8
- def setup
8
+ def before_all
9
9
  write_config()
10
10
  Camping.goes :Config
11
11
  @options = Camping::Apps.select{|a| a.name == "Config" }.first.options
12
- super
13
12
  end
14
13
 
15
- def teardown
14
+ def after_all
16
15
  trash_config()
17
- super
18
16
  end
19
17
 
20
18
  def test_config
@@ -40,4 +40,43 @@ class Generator::Test < TestCase
40
40
 
41
41
  end
42
42
 
43
+ # Generates expected directory Structure
44
+ #
45
+ # Camping has an expected directory structure:
46
+ #
47
+ # .gitignore
48
+ # .ruby-version
49
+ # Gemfile
50
+ # Rakefile
51
+ # camp.rb
52
+ # config.kdl
53
+ # src/
54
+ # lib/
55
+ # public/
56
+ # test/
57
+ # apps/
58
+ #
59
+ # This test checks to make certain that the generator command creates this
60
+ # directory structure.
61
+ def test_app_generates_directory_structure
62
+ move_to_tmp
63
+ Camping::Commands.new_cmd
64
+
65
+ res, ignored = [Dir.glob('*').select {|f| !File.directory? f },
66
+ Dir.glob('*').select {|f| File.directory? f }], Dir.glob(".*")
67
+
68
+ assert res[0].include?('Gemfile'), "mising Gemfile"
69
+ assert res[0].include?('README.md'), "missing README.md"
70
+ assert res[0].include?('Rakefile'), "missing Rakefile"
71
+ assert res[0].include?('camp.rb'), "missing camp.rb"
72
+ assert res[0].include?('config.kdl'), "missing config.kdl"
73
+ assert res[1].include?('public'), "missing public folder."
74
+ assert res[1].include?('test'), "missing test folder."
75
+
76
+ assert ignored.include?('.gitignore'), ".gitignore is missing."
77
+ assert ignored.include?('.ruby-version'), ".ruby-version is missing."
78
+
79
+ leave_tmp
80
+ end
81
+
43
82
  end
@@ -2,6 +2,13 @@ require 'test_helper'
2
2
  require 'camping'
3
3
  require 'camping/commands'
4
4
 
5
+ # The idea behind the inception stuff is that you can inherit settings
6
+ # templates, etc... from a Camping app and just... extend it.
7
+ # This is a tabled, but not abandoned idea. It became a little difficult
8
+ # to inherit all of these things, along with views, Models, etc... that's
9
+ # associated with a camping app. Getting this to work would mean a big
10
+ # rewrite of Camping's core, which is a no no.
11
+
5
12
  Camping.goes :Inception
6
13
  # Inception.goes :Leonardo
7
14
  # Leonardo.goes :Donatello
@@ -0,0 +1,53 @@
1
+ require 'test_helper'
2
+ require 'fileutils'
3
+ require 'camping/loader'
4
+
5
+ module Donuts end
6
+ module Loader end
7
+
8
+ # for Reloading stuff
9
+ module TestCaseLoaderToo
10
+ def loader
11
+ @loader ||= Camping::Loader.new(file)
12
+ end
13
+
14
+ def before_all
15
+ super
16
+ move_to_loader
17
+ loader.reload!
18
+ end
19
+
20
+ def after_all
21
+ leave_loader
22
+ super
23
+ end
24
+ end
25
+
26
+ class Donuts::Test < TestCase
27
+ include TestCaseLoaderToo
28
+ BASE = File.expand_path('../apps/loader/camp', __FILE__)
29
+ def file; BASE + '.rb' end
30
+
31
+ def test_that_our_apps_are_there
32
+ assert loader.apps.include?(:Donuts), "Donuts not found: #{loader.apps}"
33
+ assert loader.apps.include?(:Loader), "Loader not found: #{loader.apps}"
34
+ end
35
+
36
+ def test_output
37
+ # Checks that the view is overwritten successfully more than once.
38
+ get '/'
39
+ assert_body "chunky bacon", "Response is wrong in the loader."
40
+ assert_equal "text/html", last_response.headers['content-type']
41
+
42
+ # Checks that the view is not overwritten, because it's not reopened.
43
+ get '/post'
44
+ assert_body "_why", "Response is wrong in the loader."
45
+ assert_equal "text/html", last_response.headers['content-type']
46
+
47
+ # Checks that a downstream view is loaded properly.
48
+ get '/people'
49
+ assert_body "People are great am I right?", "Response is wrong in the loader."
50
+ assert_equal "text/html", last_response.headers['content-type']
51
+ end
52
+
53
+ end
data/test/app_sessions.rb CHANGED
@@ -44,8 +44,8 @@ class Sessions::Test < TestCase
44
44
  app.set :secret, "whateverloser"
45
45
  begin
46
46
  app.include Camping::Session
47
- rescue InsecureSecret => e
48
- message = "You're Session Secret is too short. Minimum length is 64."
47
+ rescue InsecureSecretError => e
48
+ message = "Your Session Secret is too short. Minimum length is 64."
49
49
  assert_equal(e.message, message, "You're session secret wasn't long enough.")
50
50
  end
51
51
 
@@ -54,11 +54,11 @@ class Sessions::Test < TestCase
54
54
  begin
55
55
  app.set :secret, "whateverloserwhateverloserwhateverloserwhateverloserwhateverloser"
56
56
  app.include Camping::Session
57
- rescue InsecureSecret => e
57
+ rescue InsecureSecretError => e
58
58
  message = e
59
59
  end
60
60
 
61
- assert_equal(e, message, "You're session secret wasn't long enough.")
61
+ assert_equal(e, message, "Your session secret wasn't long enough.")
62
62
  end
63
63
  end
64
64
 
@@ -0,0 +1,18 @@
1
+ module Donuts
2
+ module Controllers
3
+ class Index
4
+ def get
5
+ render :index
6
+ end
7
+ end
8
+ end
9
+
10
+ # how to add a layout to every page
11
+ module Views
12
+
13
+ def index
14
+ "chunky bacon"
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,15 @@
1
+ module Donuts
2
+ module Controllers
3
+ class Index
4
+ def get
5
+ "We've got lots of donuts!"
6
+ end
7
+ end
8
+
9
+ class People
10
+ def get
11
+ "People are great am I right?"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,35 @@
1
+ require 'camping'
2
+
3
+ Camping.goes :Loader
4
+
5
+ $LOAD_PATH << File.dirname(__FILE__)
6
+
7
+ Camping.goes :Donuts
8
+
9
+ module Donuts
10
+ module Controllers
11
+ class Index
12
+ def get
13
+ render :index
14
+ end
15
+ end
16
+ class Post
17
+ def get
18
+ render :post
19
+ end
20
+ end
21
+ end
22
+
23
+ # how to add a layout to every page
24
+ module Views
25
+
26
+ def index
27
+ "_why"
28
+ end
29
+
30
+ def post
31
+ "_why"
32
+ end
33
+
34
+ end
35
+ end
@@ -1,5 +1,5 @@
1
1
  $LOAD_PATH << File.dirname(__FILE__) + '/../'
2
+ $LOAD_PATH << File.dirname(__FILE__) + '/'
2
3
 
3
4
  require 'reloader'
4
5
  run Reloader
5
-
@@ -1,2 +1 @@
1
1
  $counter += 1
2
-
@@ -3,5 +3,4 @@ require 'camping'
3
3
  Camping.goes :Reloader
4
4
 
5
5
  $LOAD_PATH << File.dirname(__FILE__)
6
- require 'reloader/reload_me'
7
-
6
+ require 'reload_me'
@@ -0,0 +1,78 @@
1
+ require_relative 'test_helper'
2
+ require 'fileutils'
3
+ require 'camping/loader'
4
+
5
+ $counter = 0
6
+
7
+ # for Reloading stuff
8
+ module TestCaseLoader
9
+
10
+ def loader
11
+ @loader ||= Camping::Loader.new(file)
12
+ end
13
+
14
+ def before_all
15
+ super
16
+ move_to_reloader
17
+ loader.reload!
18
+ assert Object.const_defined?(:Reloader), "Reloader didn't load app"
19
+ # puts "before_all called"
20
+ end
21
+
22
+ def after_all
23
+ # puts "after_all called"
24
+ assert Object.const_defined?(:Reloader), "Test removed app"
25
+ loader.remove_constants
26
+ # breaks in CI for some reason.
27
+ # assert !Object.const_defined?(:Reloader), "Loader didn't remove app"
28
+ leave_reloader
29
+ super
30
+ end
31
+
32
+ end
33
+
34
+ class TestConfigRu < TestCase
35
+ include TestCaseLoader
36
+
37
+ BASE = File.expand_path('../apps/reloader', __FILE__)
38
+ def file; BASE + '/config.ru' end
39
+
40
+ def setup
41
+ super
42
+ $counter = 0
43
+ loader.reload!
44
+ # puts "setup called"
45
+ end
46
+
47
+ def test_counter
48
+ assert_equal 1, $counter
49
+ end
50
+
51
+ def test_forced_reload
52
+ loader.reload!
53
+ assert_equal 2, $counter
54
+ end
55
+
56
+ def test_that_touch_was_touched
57
+ FileUtils.touch(BASE + '/reloader.rb')
58
+ assert_equal 1, $counter
59
+ end
60
+
61
+ def test_mtime_reload
62
+ loader.reload
63
+ assert_equal 1, $counter
64
+
65
+ FileUtils.touch(BASE + '/reloader.rb')
66
+ loader.reload
67
+ assert_equal 2, $counter
68
+
69
+ FileUtils.touch(BASE + '/reload_me.rb')
70
+ loader.reload
71
+ assert_equal 3, $counter
72
+ end
73
+
74
+ def test_name
75
+ assert_equal Reloader, loader.apps[:reloader]
76
+ end
77
+
78
+ end
@@ -0,0 +1,81 @@
1
+ require_relative 'test_helper'
2
+ require 'fileutils'
3
+ require 'camping/loader'
4
+
5
+ $counter = 0
6
+
7
+ # for Reloading stuff
8
+ module TestCaseLoader
9
+
10
+ def loader
11
+ @loader ||= Camping::Loader.new(file)
12
+ end
13
+
14
+ def before_all
15
+ super
16
+ move_to_reloader
17
+ loader.reload!
18
+ assert Object.const_defined?(:Reloader), "Reloader didn't load app"
19
+ # puts "before_all called"
20
+ end
21
+
22
+ def after_all
23
+ # puts "after_all called"
24
+ assert Object.const_defined?(:Reloader), "Test removed app"
25
+ loader.remove_constants
26
+ assert !Object.const_defined?(:Reloader), "Loader didn't remove app"
27
+ leave_reloader
28
+ super
29
+ end
30
+
31
+ end
32
+
33
+ class TestLoader < TestCase
34
+ include TestCaseLoader
35
+
36
+ BASE = File.expand_path('../apps/reloader', __FILE__)
37
+ def file; BASE + '/reloader.rb' end
38
+
39
+ def setup
40
+ super
41
+ $counter = 0
42
+ loader.reload!
43
+ # puts "setup called"
44
+ end
45
+
46
+ def test_counter
47
+ assert_equal 1, $counter
48
+ end
49
+
50
+ def test_forced_reload
51
+ loader.reload!
52
+ assert_equal 2, $counter
53
+ end
54
+
55
+ def test_that_touch_was_touched
56
+ FileUtils.touch(BASE + '/reloader.rb')
57
+ assert_equal 1, $counter
58
+ end
59
+
60
+ def test_mtime_reload
61
+ loader.reload
62
+ assert_equal 1, $counter
63
+
64
+ FileUtils.touch(BASE + '/reloader.rb')
65
+ loader.reload
66
+ assert_equal 2, $counter
67
+
68
+ FileUtils.touch(BASE + '/reload_me.rb')
69
+ loader.reload
70
+ assert_equal 3, $counter
71
+ end
72
+ end
73
+
74
+ # class TestConfigRu < TestLoader
75
+ # BASE = File.expand_path('../apps/reloader', __FILE__)
76
+ # def file; BASE + '/config.ru' end
77
+
78
+ # def test_name
79
+ # assert_equal Reloader, loader.apps[:reloader]
80
+ # end
81
+ # end
data/test/test_helper.rb CHANGED
@@ -14,7 +14,8 @@ end
14
14
 
15
15
  require 'minitest/autorun'
16
16
  require 'rack/test'
17
- require "minitest/reporters"
17
+ require 'minitest/reporters'
18
+ require 'minitest/hooks'
18
19
  Minitest::Reporters.use! [Minitest::Reporters::DefaultReporter.new(:color => true)]
19
20
 
20
21
 
@@ -32,6 +33,40 @@ module CommandLineCommands
32
33
  `rm -rf test/tmp` if File.exist?('test/tmp')
33
34
  end
34
35
 
36
+ # reloader helpers:
37
+ # move_to_apps
38
+ # moves to the apps directory in /test
39
+ def move_to_reloader
40
+ @original_dir = Dir.pwd
41
+ Dir.chdir "test"
42
+ Dir.chdir "apps"
43
+ Dir.chdir "reloader"
44
+ Dir.mkdir("apps") unless Dir.exist?("apps")
45
+ Dir.mkdir("lib") unless Dir.exist?("lib")
46
+ end
47
+
48
+ # deletes the temporary directories found in the /apps directory for reloader testing.
49
+ def leave_reloader
50
+ Dir.chdir @original_dir
51
+ `rm -rf test/apps/reloader/apps` if File.exist?('test/apps/reloader/apps')
52
+ `rm -rf test/apps/reloader/lib` if File.exist?('test/apps/reloader/lib')
53
+ end
54
+
55
+ # Moves to the loader directory
56
+ def move_to_loader
57
+ @original_dir = Dir.pwd
58
+ Dir.chdir "test"
59
+ Dir.chdir "apps"
60
+ Dir.chdir "loader"
61
+ Dir.mkdir("apps") unless Dir.exist?("apps")
62
+ Dir.mkdir("lib") unless Dir.exist?("lib")
63
+ end
64
+
65
+ # deletes the temporary directories found in the /apps directory for reloader testing.
66
+ def leave_loader
67
+ Dir.chdir @original_dir
68
+ end
69
+
35
70
  def write(file, content)
36
71
  raise "cannot write nil" unless file
37
72
  file = tmp_file(file)
@@ -70,6 +105,7 @@ end
70
105
  class TestCase < MiniTest::Test
71
106
  include Rack::Test::Methods
72
107
  include CommandLineCommands
108
+ include Minitest::Hooks
73
109
 
74
110
  def self.inherited(mod)
75
111
  mod.app = Object.const_get(mod.to_s[/\w+/])
@@ -80,6 +116,11 @@ class TestCase < MiniTest::Test
80
116
  attr_accessor :app
81
117
  end
82
118
 
119
+ def setup
120
+ super
121
+ Camping.make_camp
122
+ end
123
+
83
124
  def body() last_response.body end
84
125
  def app() self.class.app end
85
126
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: camping
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.2
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - why the lucky stiff
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-04-18 00:00:00.000000000 Z
11
+ date: 2023-06-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mab
@@ -153,14 +153,15 @@ files:
153
153
  - lib/camping-unabridged.rb
154
154
  - lib/camping.rb
155
155
  - lib/camping/ar.rb
156
+ - lib/camping/campguide.rb
156
157
  - lib/camping/commands.rb
157
158
  - lib/camping/gear/filters.rb
158
159
  - lib/camping/gear/inspection.rb
159
160
  - lib/camping/gear/kuddly.rb
160
161
  - lib/camping/gear/nancy.rb
162
+ - lib/camping/loader.rb
161
163
  - lib/camping/loads.rb
162
164
  - lib/camping/mab.rb
163
- - lib/camping/reloader.rb
164
165
  - lib/camping/server.rb
165
166
  - lib/camping/session.rb
166
167
  - lib/camping/template.rb
@@ -177,25 +178,30 @@ files:
177
178
  - test/app_helpers.rb
178
179
  - test/app_inception.rb
179
180
  - test/app_inline_templates.rb
181
+ - test/app_loader.rb
180
182
  - test/app_markup.rb
181
183
  - test/app_migrations.rb
182
184
  - test/app_partials.rb
183
185
  - test/app_prefixed.rb
184
- - test/app_reloader.rb
185
186
  - test/app_route_generating.rb
186
187
  - test/app_sessions.rb
187
188
  - test/app_simple.rb
188
189
  - test/apps/env_debug.rb
189
190
  - test/apps/forms.rb
190
191
  - test/apps/forward_to_other_controller.rb
192
+ - test/apps/loader/apps/donuts.rb
193
+ - test/apps/loader/apps/donuts/controllers/index.rb
194
+ - test/apps/loader/camp.rb
191
195
  - test/apps/migrations.rb
192
196
  - test/apps/misc.rb
193
- - test/apps/reloader.rb
194
197
  - test/apps/reloader/config.ru
195
198
  - test/apps/reloader/reload_me.rb
199
+ - test/apps/reloader/reloader.rb
196
200
  - test/apps/reloader_indirect.rb
197
201
  - test/apps/sessions.rb
202
+ - test/config_reloader.rb
198
203
  - test/gear/gear_nancy.rb
204
+ - test/reload_reloader.rb
199
205
  - test/test_helper.rb
200
206
  homepage: http://camping.rubyforge.org/
201
207
  licenses: []
data/test/app_reloader.rb DELETED
@@ -1,69 +0,0 @@
1
- require 'test_helper'
2
- require 'fileutils'
3
- require 'camping/reloader'
4
-
5
- $counter = 0
6
-
7
- module TestCaseReloader
8
- def reloader
9
- @reloader ||= Camping::Reloader.new(file)
10
- end
11
-
12
- def setup
13
- super
14
- reloader.reload!
15
- assert Object.const_defined?(:Reloader), "Reloader didn't load app"
16
- end
17
-
18
- def teardown
19
- super
20
- assert Object.const_defined?(:Reloader), "Test removed app"
21
- reloader.remove_apps
22
- assert !Object.const_defined?(:Reloader), "Reloader didn't remove app"
23
- end
24
- end
25
-
26
- class TestReloader < TestCase
27
- include TestCaseReloader
28
- BASE = File.expand_path('../apps/reloader', __FILE__)
29
-
30
- def file; BASE + '.rb' end
31
-
32
- def setup
33
- $counter = 0
34
- super
35
- end
36
-
37
- def test_counter
38
- assert_equal 1, $counter
39
- end
40
-
41
- def test_forced_reload
42
- reloader.reload!
43
- assert_equal 2, $counter
44
- end
45
-
46
- def test_mtime_reload
47
- reloader.reload
48
- assert_equal 1, $counter
49
-
50
- FileUtils.touch(BASE + '.rb')
51
- sleep 1
52
- reloader.reload
53
- assert_equal 2, $counter
54
-
55
- FileUtils.touch(BASE + '/reload_me.rb')
56
- sleep 1
57
- reloader.reload
58
- assert_equal 3, $counter
59
- end
60
- end
61
-
62
- class TestConfigRu < TestReloader
63
- BASE = File.expand_path('../apps/reloader', __FILE__)
64
- def file; BASE + '/config.ru' end
65
-
66
- def test_name
67
- assert_equal Reloader, reloader.apps[:reloader]
68
- end
69
- end