radiant 0.6.7 → 0.6.8

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of radiant might be problematic. Click here for more details.

Files changed (96) hide show
  1. data/CHANGELOG +35 -3
  2. data/CONTRIBUTORS +11 -1
  3. data/README +5 -3
  4. data/app/controllers/admin/welcome_controller.rb +7 -0
  5. data/app/migrate/020_add_session_info_to_users.rb +11 -0
  6. data/app/models/page.rb +22 -9
  7. data/app/models/standard_tags.rb +133 -10
  8. data/app/models/user.rb +9 -1
  9. data/app/views/admin/page/edit.html.haml +5 -4
  10. data/app/views/admin/welcome/login.html.haml +42 -24
  11. data/app/views/layouts/application.html.haml +1 -1
  12. data/config/environment.rb +4 -2
  13. data/db/migrate/020_add_session_info_to_users.rb +11 -0
  14. data/db/migrate/021_remove_session_expire_from_users.rb +9 -0
  15. data/db/schema.rb +3 -2
  16. data/lib/generators/instance/instance_generator.rb +2 -1
  17. data/lib/generators/instance/templates/instance_environment.rb +5 -3
  18. data/lib/login_system.rb +13 -0
  19. data/lib/radiant.rb +1 -1
  20. data/lib/radiant/admin_ui.rb +21 -21
  21. data/lib/radiant/extension/script.rb +251 -0
  22. data/lib/radiant/extension_loader.rb +22 -20
  23. data/lib/radiant/initializer.rb +1 -1
  24. data/lib/radiant/setup.rb +2 -0
  25. data/lib/tasks/framework.rake +39 -29
  26. data/public/500.html +1 -1
  27. data/public/javascripts/admin/admin.js +11 -9
  28. data/script/extension +5 -0
  29. data/spec/controllers/admin/user_controller_spec.rb +1 -1
  30. data/spec/controllers/admin/welcome_controller_spec.rb +31 -5
  31. data/spec/controllers/site_controller_spec.rb +15 -2
  32. data/spec/lib/login_system_spec.rb +106 -60
  33. data/spec/lib/radiant/extension/script_spec.rb +349 -0
  34. data/spec/lib/radiant/extension_loader_spec.rb +3 -0
  35. data/spec/models/page_spec.rb +62 -2
  36. data/spec/models/standard_tags_spec.rb +150 -3
  37. data/spec/models/user_spec.rb +28 -0
  38. data/spec/scenarios/file_not_found_scenario.rb +5 -0
  39. data/spec/scenarios/pages_scenario.rb +6 -0
  40. data/spec/scenarios/snippets_scenario.rb +4 -0
  41. data/test/fixtures/users.yml +11 -6
  42. data/vendor/plugins/haml/FAQ +138 -0
  43. data/vendor/plugins/haml/REVISION +1 -0
  44. data/vendor/plugins/haml/Rakefile +54 -62
  45. data/vendor/plugins/haml/VERSION +1 -1
  46. data/vendor/plugins/haml/init.rb +6 -1
  47. data/vendor/plugins/haml/lib/haml.rb +72 -12
  48. data/vendor/plugins/haml/lib/haml/buffer.rb +47 -40
  49. data/vendor/plugins/haml/lib/haml/engine.rb +20 -30
  50. data/vendor/plugins/haml/lib/haml/error.rb +4 -5
  51. data/vendor/plugins/haml/lib/haml/exec.rb +4 -2
  52. data/vendor/plugins/haml/lib/haml/filters.rb +30 -15
  53. data/vendor/plugins/haml/lib/haml/helpers.rb +47 -28
  54. data/vendor/plugins/haml/lib/haml/helpers/action_view_mods.rb +74 -25
  55. data/vendor/plugins/haml/lib/haml/precompiler.rb +92 -51
  56. data/vendor/plugins/haml/lib/haml/template.rb +11 -3
  57. data/vendor/plugins/haml/lib/haml/template/patch.rb +1 -1
  58. data/vendor/plugins/haml/lib/sass.rb +26 -3
  59. data/vendor/plugins/haml/lib/sass/constant.rb +26 -57
  60. data/vendor/plugins/haml/lib/sass/constant/literal.rb +1 -0
  61. data/vendor/plugins/haml/lib/sass/constant/nil.rb +9 -0
  62. data/vendor/plugins/haml/lib/sass/css.rb +17 -2
  63. data/vendor/plugins/haml/lib/sass/engine.rb +11 -5
  64. data/vendor/plugins/haml/test/haml/engine_test.rb +57 -39
  65. data/vendor/plugins/haml/test/haml/helper_test.rb +20 -4
  66. data/vendor/plugins/haml/test/haml/html2haml_test.rb +1 -3
  67. data/vendor/plugins/haml/test/haml/results/content_for_layout.xhtml +1 -2
  68. data/vendor/plugins/haml/test/haml/results/eval_suppressed.xhtml +2 -4
  69. data/vendor/plugins/haml/test/haml/results/filters.xhtml +12 -8
  70. data/vendor/plugins/haml/test/haml/results/helpers.xhtml +2 -5
  71. data/vendor/plugins/haml/test/haml/results/just_stuff.xhtml +1 -3
  72. data/vendor/plugins/haml/test/haml/results/nuke_inner_whitespace.xhtml +40 -0
  73. data/vendor/plugins/haml/test/haml/results/nuke_outer_whitespace.xhtml +148 -0
  74. data/vendor/plugins/haml/test/haml/results/original_engine.xhtml +2 -4
  75. data/vendor/plugins/haml/test/haml/results/tag_parsing.xhtml +1 -6
  76. data/vendor/plugins/haml/test/haml/results/very_basic.xhtml +2 -4
  77. data/vendor/plugins/haml/test/haml/results/whitespace_handling.xhtml +13 -21
  78. data/vendor/plugins/haml/test/haml/template_test.rb +31 -48
  79. data/vendor/plugins/haml/test/haml/templates/filters.haml +13 -0
  80. data/vendor/plugins/haml/test/haml/templates/helpers.haml +1 -1
  81. data/vendor/plugins/haml/test/haml/templates/just_stuff.haml +0 -1
  82. data/vendor/plugins/haml/test/haml/templates/nuke_inner_whitespace.haml +32 -0
  83. data/vendor/plugins/haml/test/haml/templates/nuke_outer_whitespace.haml +144 -0
  84. data/vendor/plugins/haml/test/haml/templates/partials.haml +1 -1
  85. data/vendor/plugins/haml/test/haml/templates/tag_parsing.haml +0 -3
  86. data/vendor/plugins/haml/test/haml/templates/whitespace_handling.haml +10 -10
  87. data/vendor/plugins/haml/test/sass/engine_test.rb +11 -5
  88. data/vendor/plugins/haml/test/sass/plugin_test.rb +2 -6
  89. data/vendor/plugins/haml/test/sass/results/constants.css +2 -0
  90. data/vendor/plugins/haml/test/sass/templates/constants.sass +3 -0
  91. data/vendor/plugins/haml/test/{haml/test_helper.rb → test_helper.rb} +4 -3
  92. metadata +21 -11
  93. data/vendor/plugins/haml/TODO +0 -9
  94. data/vendor/plugins/haml/extra/haml-mode.el +0 -328
  95. data/vendor/plugins/haml/extra/sass-mode.el +0 -88
  96. data/vendor/plugins/haml/test/profile.rb +0 -65
@@ -0,0 +1,349 @@
1
+ require File.dirname(__FILE__) + "/../../../spec_helper"
2
+ require 'radiant/extension/script'
3
+
4
+ describe "Radiant::Extension::Script" do
5
+ it "should determine which subscript to run" do
6
+ Radiant::Extension::Script::Install.should_receive(:new)
7
+ Radiant::Extension::Script.execute ['install']
8
+
9
+ Radiant::Extension::Script::Uninstall.should_receive(:new)
10
+ Radiant::Extension::Script.execute ['uninstall']
11
+ end
12
+
13
+ it "should pass the command-line args to the subscript" do
14
+ Radiant::Extension::Script::Install.should_receive(:new).with(['page_attachments'])
15
+ Radiant::Extension::Script.execute ['install', 'page_attachments']
16
+ end
17
+ end
18
+
19
+ describe "Radiant::Extension::Script::Util" do
20
+ include Radiant::Extension::Script::Util
21
+
22
+ it "should determine an extension name from a camelized string" do
23
+ to_extension_name("PageAttachments").should == 'page_attachments'
24
+ end
25
+
26
+ it "should determine an extension name from a hyphened name" do
27
+ to_extension_name("page-attachments").should == 'page_attachments'
28
+ end
29
+
30
+ it "should determine an extension name from an underscored name" do
31
+ to_extension_name("page_attachments").should == 'page_attachments'
32
+ end
33
+
34
+ it "should determine extension paths" do
35
+ # Bad coupling, but will work by default
36
+ extension_paths.should be_kind_of(Array)
37
+ extension_paths.should include("#{RADIANT_ROOT}/vendor/extensions/archive")
38
+ end
39
+
40
+ it "should determine whether an extension is installed" do
41
+ # Bad coupling, but will work by default
42
+ self.extension_name = 'archive'
43
+ self.should be_installed
44
+ end
45
+
46
+ it "should load all extensions from the web service" do
47
+ Registry::Extension.should_receive(:find).with(:all).and_return([1,2,3])
48
+ load_extensions.should == [1,2,3]
49
+ end
50
+
51
+ it "should find an extension of the given name from the web service" do
52
+ @ext_mock = mock("Extension", :name => 'page_attachments')
53
+ should_receive(:load_extensions).and_return([@ext_mock])
54
+ self.extension_name = 'page_attachments'
55
+ find_extension.should == @ext_mock
56
+ end
57
+ end
58
+
59
+ describe "Radiant::Extension::Script::Install" do
60
+
61
+ before :each do
62
+ @extension = mock('Extension', :install => true, :name => 'page_attachments')
63
+ Registry::Extension.stub!(:find).and_return([@extension])
64
+ end
65
+
66
+ it "should read the extension name from the command line" do
67
+ @install = Radiant::Extension::Script::Install.new ['page_attachments']
68
+ @install.extension_name.should == 'page_attachments'
69
+ end
70
+
71
+ it "should attempt to find the extension and install it" do
72
+ @extension.should_receive(:install).and_return(true)
73
+ @install = Radiant::Extension::Script::Install.new ['page_attachments']
74
+ end
75
+
76
+ it "should fail if an extension name is not given" do
77
+ lambda { Radiant::Extension::Script::Install.new []}.should raise_error
78
+ end
79
+ end
80
+
81
+ describe "Radiant::Extension::Script::Uninstall" do
82
+
83
+ before :each do
84
+ @extension = mock('Extension', :uninstall => true, :name => 'archive')
85
+ Registry::Extension.stub!(:find).and_return([@extension])
86
+ end
87
+
88
+ it "should read the extension name from the command line" do
89
+ @uninstall = Radiant::Extension::Script::Uninstall.new ['archive']
90
+ @uninstall.extension_name.should == 'archive'
91
+ end
92
+
93
+ it "should attempt to find the extension and uninstall it" do
94
+ @extension.should_receive(:uninstall).and_return(true)
95
+ @uninstall = Radiant::Extension::Script::Uninstall.new ['archive']
96
+ end
97
+
98
+ it "should fail if an extension name is not given" do
99
+ lambda { Radiant::Extension::Script::Uninstall.new []}.should raise_error
100
+ end
101
+ end
102
+
103
+ describe "Registry::Action" do
104
+ before :each do
105
+ @action = Registry::Action.new
106
+ end
107
+
108
+ it "should shell out with the specified rake task" do
109
+ @action.should_receive(:`).with("rake sample RAILS_ENV=#{RAILS_ENV}")
110
+ @action.rake('sample')
111
+ end
112
+ end
113
+
114
+ describe "Registry::Installer" do
115
+ before :each do
116
+ @installer = Registry::Installer.new('http://localhost/', 'example')
117
+ end
118
+
119
+ it "should set the name and url of the extension" do
120
+ @installer.url.should == 'http://localhost/'
121
+ @installer.name.should == 'example'
122
+ end
123
+
124
+ it "should install by copying, migrating and updating" do
125
+ @installer.should_receive(:copy_to_vendor_extensions)
126
+ @installer.should_receive(:migrate)
127
+ @installer.should_receive(:update)
128
+ @installer.install
129
+ end
130
+
131
+ it "should copy the extension to vendor/extensions" do
132
+ @installer.path = "/tmp"
133
+ FileUtils.should_receive(:cp_r).with('/tmp', "#{RAILS_ROOT}/vendor/extensions/example")
134
+ FileUtils.should_receive(:rm_r).with('/tmp')
135
+ @installer.copy_to_vendor_extensions
136
+ end
137
+
138
+ it "should run the rake migrate task" do
139
+ @installer.should_receive(:rake).with('radiant:extensions:example:migrate')
140
+ @installer.migrate
141
+ end
142
+
143
+ it "should run the rake update task" do
144
+ @installer.should_receive(:rake).with('radiant:extensions:example:update')
145
+ @installer.update
146
+ end
147
+ end
148
+
149
+ describe "Registry::Uninstaller" do
150
+ before :each do
151
+ @extension = mock('Extension', :name => 'example')
152
+ @uninstaller = Registry::Uninstaller.new(@extension)
153
+ end
154
+
155
+ it "should migrate down" do
156
+ @uninstaller.should_receive(:rake).with("radiant:extensions:example:migrate VERSION=0")
157
+ @uninstaller.migrate_down
158
+ end
159
+
160
+ it "should remove the extension directory" do
161
+ FileUtils.should_receive(:rm_r).with("#{RAILS_ROOT}/vendor/extensions/example")
162
+ @uninstaller.remove_extension_directory
163
+ end
164
+
165
+ it "should uninstall by migrating down and removing the directory" do
166
+ @uninstaller.should_receive(:migrate_down)
167
+ @uninstaller.should_receive(:remove_extension_directory)
168
+ @uninstaller.uninstall
169
+ end
170
+ end
171
+
172
+ describe "Registry::Checkout" do
173
+ before :each do
174
+ @extension = mock("Extension", :name => 'example', :repository_url => 'http://localhost/')
175
+ @checkout = Registry::Checkout.new(@extension)
176
+ @methods = [:copy_to_vendor_extensions, :migrate, :update].each do |method|
177
+ @checkout.stub!(method).and_return(true)
178
+ end
179
+ end
180
+
181
+ it "should set the name and url" do
182
+ @checkout.name.should == 'example'
183
+ @checkout.url.should == 'http://localhost/'
184
+ end
185
+
186
+ it "should defer the checkout command to concrete subclasses" do
187
+ lambda { @checkout.checkout_command }.should raise_error
188
+ end
189
+
190
+ it "should install by checking out the source and then proceeding with the normal installation" do
191
+ @methods.each { |method| @checkout.should_receive(method) }
192
+ @checkout.should_receive(:checkout)
193
+ @checkout.install
194
+ end
195
+
196
+ it "should checkout the source" do
197
+ @checkout.stub!(:checkout_command).and_return('echo')
198
+ @checkout.should_receive(:system).with(/^cd (.*); echo/)
199
+ @checkout.checkout
200
+ @checkout.path.should_not be_nil
201
+ @checkout.path.should =~ /example/
202
+ end
203
+ end
204
+
205
+ describe "Registry::Download" do
206
+ before :each do
207
+ @extension = mock("Extension", :name => 'example', :download_url => 'http://localhost/example.pkg')
208
+ @download = Registry::Download.new(@extension)
209
+ @methods = [:copy_to_vendor_extensions, :migrate, :update].each do |method|
210
+ @download.stub!(method).and_return(true)
211
+ end
212
+ end
213
+
214
+ it "should set the name and url" do
215
+ @download.name.should == 'example'
216
+ @download.url.should == 'http://localhost/example.pkg'
217
+ end
218
+
219
+ it "should defer the unpack command to concrete subclasses" do
220
+ lambda { @download.unpack }.should raise_error
221
+ end
222
+
223
+ it "should install by downloading and unpacking and then proceeding with the normal installation" do
224
+ @methods.each { |method| @download.should_receive(method) }
225
+ @download.should_receive(:download)
226
+ @download.should_receive(:unpack)
227
+ @download.install
228
+ end
229
+
230
+ it "should determine the filename" do
231
+ @download.filename.should == 'example.pkg'
232
+ end
233
+
234
+ it "should download the file" do
235
+ @file = mock('file')
236
+ File.should_receive(:open).with(/example\.pkg/, 'w').and_yield(@file)
237
+ @download.should_receive(:open).and_return(StringIO.new('test'))
238
+ @file.should_receive(:write).with('test')
239
+ @download.download
240
+ end
241
+ end
242
+
243
+ describe "Registry::Git" do
244
+ before :each do
245
+ @extension = mock("Extension", :name => 'example', :repository_url => 'http://localhost/')
246
+ @git = Registry::Git.new(@extension)
247
+ end
248
+
249
+ it "should use git to clone the repository" do
250
+ @git.checkout_command.should == 'git clone http://localhost/ example'
251
+ end
252
+ end
253
+
254
+ describe "Registry::Subversion" do
255
+ before :each do
256
+ @extension = mock("Extension", :name => 'example', :repository_url => 'http://localhost/')
257
+ @svn = Registry::Subversion.new(@extension)
258
+ end
259
+
260
+ it "should use svn to checkout the repository" do
261
+ @svn.checkout_command.should == 'svn checkout http://localhost/ example'
262
+ end
263
+ end
264
+
265
+ describe "Registry::Gem" do
266
+ before :each do
267
+ @extension = mock("Extension", :name => 'example', :download_url => 'http://localhost/example-1.0.0.gem')
268
+ @gem = Registry::Gem.new(@extension)
269
+ end
270
+
271
+ it "should download the gem and install it if it is not already installed" do
272
+ @gem.should_receive(:gem).and_raise(::Gem::LoadError.new)
273
+ @file = mock('file')
274
+ File.should_receive(:open).with(/example-1.0.0\.gem/, 'w').and_yield(@file)
275
+ @gem.should_receive(:open).and_return(StringIO.new('test'))
276
+ @file.should_receive(:write).with('test')
277
+ @gem.should_receive(:`).with("gem install example-1.0.0.gem")
278
+ @gem.download
279
+ end
280
+
281
+ it "should not download the gem if it is already installed" do
282
+ @gem.should_receive(:gem).and_return(true)
283
+ File.should_not_receive(:open)
284
+ @gem.should_not_receive(:open)
285
+ @gem.should_not_receive(:`)
286
+ @gem.download
287
+ end
288
+
289
+ it "should unpack the gem and capture the path" do
290
+ @gem.should_receive(:`).with(/gem unpack example/).and_return("Unpacked gem: '/tmp/example-1.0.0'")
291
+ @gem.unpack
292
+ @gem.path.should == '/tmp/example-1.0.0'
293
+ end
294
+ end
295
+
296
+ describe "Registry::Tarball" do
297
+ before :each do
298
+ @extension = mock("Extension", :name => 'example', :download_url => 'http://localhost/example-1.0.0.tar')
299
+ @tar = Registry::Tarball.new(@extension)
300
+ end
301
+
302
+ it "should unpack the tarball without compression" do
303
+ @tar.should_receive(:`).with(/tar xvf example.tar/).and_return('example-1.0.0/example_extension.rb\n')
304
+ @tar.unpack
305
+ @tar.path.should =~ /example-1\.0\.0$/
306
+ end
307
+ end
308
+
309
+ describe "Registry::Gzip" do
310
+ before :each do
311
+ @extension = mock("Extension", :name => 'example', :download_url => 'http://localhost/example-1.0.0.tar.gz')
312
+ @gzip = Registry::Gzip.new(@extension)
313
+ end
314
+
315
+ it "should unpack the archive with compression" do
316
+ @gzip.should_receive(:system).with(/gunzip example.tar.gz/)
317
+ @gzip.should_receive(:`).with(/tar xvf example.tar/).and_return('example-1.0.0/example_extension.rb\n')
318
+ @gzip.unpack
319
+ @gzip.path.should =~ /example-1\.0\.0$/
320
+ end
321
+ end
322
+
323
+ describe "Registry::Bzip2" do
324
+ before :each do
325
+ @extension = mock("Extension", :name => 'example', :download_url => 'http://localhost/example-1.0.0.tar.bz2')
326
+ @gzip = Registry::Bzip2.new(@extension)
327
+ end
328
+
329
+ it "should unpack the archive with compression" do
330
+ @gzip.should_receive(:system).with(/bunzip2 example.tar.bz2/)
331
+ @gzip.should_receive(:`).with(/tar xvf example.tar/).and_return('example-1.0.0/example_extension.rb\n')
332
+ @gzip.unpack
333
+ @gzip.path.should =~ /example-1\.0\.0$/
334
+ end
335
+ end
336
+
337
+
338
+ describe "Registry::Zip" do
339
+ before :each do
340
+ @extension = mock("Extension", :name => 'example', :download_url => 'http://localhost/example-1.0.0.zip')
341
+ @zip = Registry::Zip.new(@extension)
342
+ end
343
+
344
+ it "should unpack the zip" do
345
+ @zip.should_receive(:`).with(/unzip example-1.0.0.zip -d example/).and_return('')
346
+ @zip.unpack
347
+ @zip.path.should =~ /example$/
348
+ end
349
+ end
@@ -6,8 +6,10 @@ describe Radiant::ExtensionLoader do
6
6
  $LOAD_PATH.stub!(:unshift)
7
7
  @observer = mock("observer")
8
8
  @configuration = mock("configuration")
9
+ @admin = mock("admin_ui")
9
10
  @initializer = mock("initializer")
10
11
  @initializer.stub!(:configuration).and_return(@configuration)
12
+ @initializer.stub!(:admin).and_return(@admin)
11
13
  @instance = Radiant::ExtensionLoader.send(:new)
12
14
  @instance.initializer = @initializer
13
15
 
@@ -143,6 +145,7 @@ describe Radiant::ExtensionLoader do
143
145
  it "should activate extensions" do
144
146
  @initializer.should_receive(:initialize_default_admin_tabs)
145
147
  @initializer.should_receive(:initialize_framework_views)
148
+ @admin.should_receive(:load_default_regions)
146
149
  extensions = [BasicExtension, OverridingExtension]
147
150
  @instance.extensions = extensions
148
151
  @instance.activate_extensions
@@ -377,7 +377,15 @@ describe Page, "#find_by_url" do
377
377
  it 'should find the FileNotFoundPage when a page does not exist' do
378
378
  @page.find_by_url('/nothing-doing/').should == pages(:file_not_found)
379
379
  end
380
-
380
+
381
+ it 'should find a draft FileNotFoundPage in dev mode' do
382
+ @page.find_by_url('/drafts/no-page-here', false).should == pages(:lonely_draft_file_not_found)
383
+ end
384
+
385
+ it 'should not find a draft FileNotFoundPage in live mode' do
386
+ @page.find_by_url('/drafts/no-page-here').should_not == pages(:lonely_draft_file_not_found)
387
+ end
388
+
381
389
  it 'should find a custom file not found page' do
382
390
  @page.find_by_url('/gallery/nothing-doing/').should == pages(:no_picture)
383
391
  end
@@ -428,7 +436,14 @@ describe Page, "class" do
428
436
  it 'should allow initialization with default page status' do
429
437
  @page = Page.new_with_defaults({ 'defaults.page.status' => 'published' })
430
438
  @page.status.should == Status[:published]
431
- end
439
+ end
440
+
441
+ it 'should allow initialization with default filter' do
442
+ @page = Page.new_with_defaults({ 'defaults.page.filter' => 'Textile', 'defaults.page.parts' => 'a, b, c' })
443
+ @page.parts.each do |part|
444
+ part.filter_id.should == 'Textile'
445
+ end
446
+ end
432
447
 
433
448
  it 'should allow you to get the class name of a descendant class with a string' do
434
449
  ["", nil, "Page"].each do |value|
@@ -443,6 +458,51 @@ describe Page, "class" do
443
458
  end
444
459
  Page.is_descendant_class_name?("InvalidPage").should == false
445
460
  end
461
+
462
+ end
463
+
464
+ describe Page, "loading subclasses before bootstrap" do
465
+ before :each do
466
+ Page.connection.should_receive(:tables).and_return([])
467
+ end
468
+
469
+ it "should not attempt to search for missing subclasses" do
470
+ Page.connection.should_not_receive(:select_values).with("SELECT DISTINCT class_name FROM pages WHERE class_name <> '' AND class_name IS NOT NULL")
471
+ Page.load_subclasses
472
+ end
473
+ end
474
+
475
+ describe Page, 'loading subclasses after bootstrap' do
476
+ it "should find subclasses in extensions" do
477
+ defined?(ArchivePage).should_not be_nil
478
+ end
479
+
480
+ it "should not adjust the display name of subclasses found in extensions" do
481
+ ArchivePage.display_name.should_not match(/not installed/)
482
+ end
483
+ end
484
+
485
+ describe Page, "class which is applied to a page but not defined" do
486
+ scenario :pages
487
+
488
+ before :each do
489
+ eval(%Q{class ClassNotDefinedPage < Page; def self.missing?; false end end}, TOPLEVEL_BINDING)
490
+ create_page "Class Not Defined", :class_name => "ClassNotDefinedPage"
491
+ Object.send(:remove_const, :ClassNotDefinedPage)
492
+ Page.load_subclasses
493
+ end
494
+
495
+ it 'should be created dynamically as a new subclass of Page' do
496
+ Object.const_defined?("ClassNotDefinedPage").should == true
497
+ end
498
+
499
+ it 'should indicate that it wasn\'t defined' do
500
+ ClassNotDefinedPage.missing?.should == true
501
+ end
502
+
503
+ it "should adjust the display name to indicate that the page type is not installed" do
504
+ ClassNotDefinedPage.display_name.should match(/not installed/)
505
+ end
446
506
  end
447
507
 
448
508
  describe Page, "class find_by_url" do