camping 3.0.2 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
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