spontaneous 0.2.0.beta4 → 0.2.0.beta5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (205) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +39 -0
  3. data/Gemfile +11 -6
  4. data/Readme.markdown +136 -69
  5. data/application/css/core.css.scss +27 -7
  6. data/application/css/editing.css.scss +4 -26
  7. data/application/css/schema_error.css.scss +22 -0
  8. data/application/js/content.js +11 -3
  9. data/application/js/edit_panel.js +1 -4
  10. data/application/js/field/file.js +17 -0
  11. data/application/js/field/image.js +30 -21
  12. data/application/js/field/string.js +4 -1
  13. data/application/js/field_preview.js +21 -16
  14. data/application/js/publish.js +6 -6
  15. data/application/js/types.js +5 -13
  16. data/application/js/views.js +2 -2
  17. data/application/js/views/box_view.js +3 -2
  18. data/application/js/views/page_piece_view.js +1 -1
  19. data/application/js/views/piece_view.js +1 -1
  20. data/application/views/schema_modification_error.html.erb +13 -3
  21. data/db/migrations/20131104101935_site_must_publish_all.rb +14 -0
  22. data/lib/spontaneous.rb +0 -1
  23. data/lib/spontaneous/box_style.rb +15 -9
  24. data/lib/spontaneous/capistrano/deploy.rb +13 -1
  25. data/lib/spontaneous/change.rb +11 -13
  26. data/lib/spontaneous/cli.rb +5 -2
  27. data/lib/spontaneous/cli/assets.rb +7 -1
  28. data/lib/spontaneous/cli/console.rb +7 -1
  29. data/lib/spontaneous/cli/content.rb +35 -0
  30. data/lib/spontaneous/cli/fields.rb +3 -2
  31. data/lib/spontaneous/cli/generate.rb +5 -2
  32. data/lib/spontaneous/cli/server.rb +12 -8
  33. data/lib/spontaneous/cli/site.rb +12 -12
  34. data/lib/spontaneous/cli/user.rb +28 -14
  35. data/lib/spontaneous/collections/box_set.rb +4 -4
  36. data/lib/spontaneous/collections/field_set.rb +4 -4
  37. data/lib/spontaneous/collections/prototype_set.rb +12 -4
  38. data/lib/spontaneous/data_mapper.rb +11 -7
  39. data/lib/spontaneous/data_mapper/content_model.rb +8 -0
  40. data/lib/spontaneous/data_mapper/content_model/associations.rb +1 -1
  41. data/lib/spontaneous/data_mapper/dataset.rb +14 -2
  42. data/lib/spontaneous/data_mapper/scope.rb +33 -13
  43. data/lib/spontaneous/facet.rb +4 -0
  44. data/lib/spontaneous/field.rb +12 -12
  45. data/lib/spontaneous/field/base.rb +27 -22
  46. data/lib/spontaneous/field/boolean.rb +4 -4
  47. data/lib/spontaneous/field/date.rb +2 -2
  48. data/lib/spontaneous/field/file.rb +24 -18
  49. data/lib/spontaneous/field/html.rb +1 -1
  50. data/lib/spontaneous/field/image.rb +6 -19
  51. data/lib/spontaneous/field/location.rb +1 -1
  52. data/lib/spontaneous/field/long_string.rb +3 -3
  53. data/lib/spontaneous/field/markdown.rb +3 -3
  54. data/lib/spontaneous/field/select.rb +2 -2
  55. data/lib/spontaneous/field/string.rb +2 -2
  56. data/lib/spontaneous/field/tags.rb +2 -2
  57. data/lib/spontaneous/field/update.rb +21 -20
  58. data/lib/spontaneous/field/webvideo.rb +6 -6
  59. data/lib/spontaneous/field/webvideo/fallback.rb +2 -2
  60. data/lib/spontaneous/field/webvideo/vimeo.rb +7 -7
  61. data/lib/spontaneous/generators/site.rb +2 -2
  62. data/lib/spontaneous/generators/site/Gemfile.tt +5 -1
  63. data/lib/spontaneous/layout.rb +2 -2
  64. data/lib/spontaneous/media.rb +1 -0
  65. data/lib/spontaneous/media/file.rb +6 -5
  66. data/lib/spontaneous/media/image/attributes.rb +4 -0
  67. data/lib/spontaneous/media/image/renderable.rb +4 -4
  68. data/lib/spontaneous/media/store.rb +22 -0
  69. data/lib/spontaneous/{storage → media/store}/backend.rb +1 -1
  70. data/lib/spontaneous/{storage → media/store}/cloud.rb +1 -1
  71. data/lib/spontaneous/{storage → media/store}/local.rb +1 -1
  72. data/lib/spontaneous/media/temp_file.rb +1 -1
  73. data/lib/spontaneous/model.rb +10 -7
  74. data/lib/spontaneous/model/action.rb +7 -0
  75. data/lib/spontaneous/model/action/clean.rb +87 -0
  76. data/lib/spontaneous/model/box/allowed_types.rb +15 -1
  77. data/lib/spontaneous/model/core.rb +10 -0
  78. data/lib/spontaneous/model/core/aliases.rb +1 -1
  79. data/lib/spontaneous/model/core/content_groups.rb +1 -1
  80. data/lib/spontaneous/model/core/fields.rb +1 -1
  81. data/lib/spontaneous/model/core/modifications.rb +2 -2
  82. data/lib/spontaneous/model/core/page_search.rb +4 -0
  83. data/lib/spontaneous/model/core/publishing.rb +4 -17
  84. data/lib/spontaneous/model/core/render.rb +4 -4
  85. data/lib/spontaneous/model/core/styles.rb +2 -2
  86. data/lib/spontaneous/model/core/visibility.rb +6 -2
  87. data/lib/spontaneous/model/page.rb +6 -2
  88. data/lib/spontaneous/model/page/controllers.rb +55 -17
  89. data/lib/spontaneous/model/page/formats.rb +12 -7
  90. data/lib/spontaneous/model/page/layouts.rb +2 -2
  91. data/lib/spontaneous/model/page/locks.rb +4 -1
  92. data/lib/spontaneous/model/page/page_tree.rb +40 -6
  93. data/lib/spontaneous/output.rb +14 -52
  94. data/lib/spontaneous/output/context.rb +11 -39
  95. data/lib/spontaneous/output/context/navigation.rb +31 -0
  96. data/lib/spontaneous/output/format.rb +15 -19
  97. data/lib/spontaneous/output/renderable.rb +99 -0
  98. data/lib/spontaneous/output/store.rb +24 -0
  99. data/lib/spontaneous/output/store/backend.rb +52 -0
  100. data/lib/spontaneous/output/store/file.rb +77 -0
  101. data/lib/spontaneous/output/store/moneta.rb +117 -0
  102. data/lib/spontaneous/output/store/revision.rb +34 -0
  103. data/lib/spontaneous/output/store/store.rb +15 -0
  104. data/lib/spontaneous/output/store/transaction.rb +44 -0
  105. data/lib/spontaneous/output/template/engine.rb +17 -7
  106. data/lib/spontaneous/output/template/renderer.rb +66 -40
  107. data/lib/spontaneous/page_lock.rb +5 -7
  108. data/lib/spontaneous/page_piece.rb +2 -2
  109. data/lib/spontaneous/permissions/user.rb +14 -7
  110. data/lib/spontaneous/plugins/application/features.rb +8 -4
  111. data/lib/spontaneous/plugins/application/state.rb +12 -6
  112. data/lib/spontaneous/prototypes/box_prototype.rb +9 -10
  113. data/lib/spontaneous/prototypes/field_prototype.rb +66 -15
  114. data/lib/spontaneous/publishing/immediate.rb +30 -26
  115. data/lib/spontaneous/rack.rb +12 -7
  116. data/lib/spontaneous/rack/back.rb +43 -37
  117. data/lib/spontaneous/rack/back/base.rb +4 -4
  118. data/lib/spontaneous/rack/back/changes.rb +2 -2
  119. data/lib/spontaneous/rack/back/file.rb +16 -24
  120. data/lib/spontaneous/rack/back/map.rb +5 -5
  121. data/lib/spontaneous/rack/back/preview.rb +3 -4
  122. data/lib/spontaneous/rack/back/schema.rb +1 -1
  123. data/lib/spontaneous/rack/back/site.rb +6 -7
  124. data/lib/spontaneous/rack/front.rb +19 -16
  125. data/lib/spontaneous/rack/middleware/authenticate.rb +3 -3
  126. data/lib/spontaneous/rack/middleware/reloader.rb +3 -2
  127. data/lib/spontaneous/rack/middleware/scope.rb +25 -19
  128. data/lib/spontaneous/rack/page_controller.rb +164 -13
  129. data/lib/spontaneous/rack/public.rb +23 -62
  130. data/lib/spontaneous/rack/static.rb +2 -3
  131. data/lib/spontaneous/schema.rb +27 -8
  132. data/lib/spontaneous/schema/schema_modification.rb +9 -1
  133. data/lib/spontaneous/schema/uid.rb +2 -2
  134. data/lib/spontaneous/schema/uid_map.rb +3 -2
  135. data/lib/spontaneous/search/database.rb +2 -2
  136. data/lib/spontaneous/search/field.rb +5 -3
  137. data/lib/spontaneous/search/index.rb +12 -7
  138. data/lib/spontaneous/search/results.rb +5 -3
  139. data/lib/spontaneous/server.rb +2 -2
  140. data/lib/spontaneous/site.rb +10 -3
  141. data/lib/spontaneous/site/features.rb +26 -6
  142. data/lib/spontaneous/site/helpers.rb +9 -12
  143. data/lib/spontaneous/site/level.rb +7 -9
  144. data/lib/spontaneous/site/map.rb +9 -11
  145. data/lib/spontaneous/site/paths.rb +5 -5
  146. data/lib/spontaneous/site/publishing.rb +83 -80
  147. data/lib/spontaneous/site/schema.rb +1 -7
  148. data/lib/spontaneous/site/search.rb +8 -18
  149. data/lib/spontaneous/site/selectors.rb +60 -54
  150. data/lib/spontaneous/site/state.rb +36 -30
  151. data/lib/spontaneous/site/storage.rb +10 -16
  152. data/lib/spontaneous/state.rb +8 -0
  153. data/lib/spontaneous/style.rb +32 -33
  154. data/lib/spontaneous/version.rb +1 -1
  155. data/spontaneous.gemspec +22 -21
  156. data/test/fixtures/public/templates/layouts/default.html.cut +1 -1
  157. data/test/fixtures/public/templates/layouts/default.pdf.cut +1 -1
  158. data/test/fixtures/public/templates/layouts/default.rss.cut +1 -1
  159. data/test/fixtures/search/config/indexes.rb +1 -1
  160. data/test/fixtures/serialisation/class_hash.yaml.erb +13 -1
  161. data/test/fixtures/serialisation/root_hash.yaml.erb +10 -0
  162. data/test/functional/test_application.rb +20 -24
  163. data/test/functional/test_back.rb +26 -27
  164. data/test/functional/test_cli.rb +146 -0
  165. data/test/functional/test_front.rb +287 -216
  166. data/test/functional/test_user_manager.rb +1 -1
  167. data/test/test_helper.rb +15 -11
  168. data/test/unit/test_alias.rb +32 -25
  169. data/test/unit/test_asset_bundler.rb +1 -1
  170. data/test/unit/test_assets.rb +34 -33
  171. data/test/unit/test_authentication.rb +1 -1
  172. data/test/unit/test_boxes.rb +16 -2
  173. data/test/unit/test_changesets.rb +23 -11
  174. data/test/unit/test_content.rb +15 -0
  175. data/test/unit/test_context.rb +139 -0
  176. data/test/unit/test_controllers.rb +374 -0
  177. data/test/{experimental → unit}/test_crypt.rb +0 -0
  178. data/test/unit/test_datamapper.rb +260 -237
  179. data/test/unit/test_datamapper_content.rb +42 -12
  180. data/test/{experimental → unit}/test_features.rb +85 -3
  181. data/test/unit/test_fields.rb +117 -42
  182. data/test/unit/test_formats.rb +11 -1
  183. data/test/unit/test_generators.rb +2 -2
  184. data/test/unit/test_helpers.rb +7 -8
  185. data/test/unit/test_images.rb +39 -2
  186. data/test/unit/test_layouts.rb +14 -12
  187. data/test/unit/test_media.rb +32 -23
  188. data/test/unit/test_output_store.rb +342 -0
  189. data/test/unit/test_page.rb +8 -1
  190. data/test/unit/test_permissions.rb +11 -7
  191. data/test/unit/test_plugins.rb +3 -3
  192. data/test/unit/test_prototype_set.rb +8 -1
  193. data/test/unit/test_publishing.rb +67 -54
  194. data/test/unit/test_render.rb +91 -38
  195. data/test/unit/test_revisions.rb +4 -4
  196. data/test/unit/test_schema.rb +109 -84
  197. data/test/unit/test_search.rb +42 -42
  198. data/test/unit/test_serialisation.rb +3 -2
  199. data/test/unit/test_site.rb +39 -27
  200. data/test/unit/test_storage.rb +9 -6
  201. data/test/unit/test_styles.rb +25 -32
  202. data/test/unit/test_templates.rb +8 -4
  203. metadata +89 -54
  204. data/lib/spontaneous/model/page/request.rb +0 -105
  205. data/lib/spontaneous/storage.rb +0 -22
@@ -87,7 +87,7 @@ describe "Page" do
87
87
  Page.root.must_equal nil
88
88
  root = ErrorPage.create_root "error"
89
89
  Page.root.must_equal nil
90
- Site["#error"].must_equal root
90
+ @site["#error"].must_equal root
91
91
  end
92
92
  end
93
93
 
@@ -473,5 +473,12 @@ describe "Page" do
473
473
  it "know their owner" do
474
474
  @page_piece.owner.must_equal @piece
475
475
  end
476
+
477
+ it "tests as equal to the page target" do
478
+ @piece.reload
479
+ assert @piece.things.first == @child, "PagePiece must == its target"
480
+ assert @child == @piece.things.first, "Page must == a PagePiece that wraps it"
481
+ refute @parent == @piece.things.first
482
+ end
476
483
  end
477
484
  end
@@ -409,7 +409,7 @@ describe "Permissions" do
409
409
  it "be guaranteed unique" do
410
410
  Permissions.stubs(:random_string).returns("xxxx")
411
411
  key1 = Permissions::AccessKey.create()
412
- lambda { Permissions::AccessKey.create() }.must_raise(Sequel::DatabaseError)
412
+ lambda { Permissions::AccessKey.create() }.must_raise(Sequel::UniqueConstraintViolation)
413
413
  end
414
414
 
415
415
  it "have a creation date" do
@@ -784,6 +784,10 @@ describe "Permissions" do
784
784
  end
785
785
 
786
786
  it "only list allowed types addable by the user" do
787
+ allowed_type_names = Proc.new do |a|
788
+ a[:type]
789
+ end
790
+
787
791
  expected = [
788
792
  ["editor_level", ["D", "C"]],
789
793
  ["admin_level", ["C"]],
@@ -791,16 +795,16 @@ describe "Permissions" do
791
795
  ["mixed_level", ["C"]],
792
796
  ["default_level", ["C"]]
793
797
  ]
794
- C.export[:boxes].map { |b| [b[:name], b[:allowed_types]] }.must_equal expected
798
+ C.export[:boxes].map { |b| [b[:name], b[:allowed_types].map(&allowed_type_names)] }.must_equal expected
795
799
 
796
800
  # Permissions.with_user(@root) do
797
- C.export(@root)[:boxes].map { |b| [b[:name], b[:allowed_types]] }.must_equal expected
801
+ C.export(@root)[:boxes].map { |b| [b[:name], b[:allowed_types].map(&allowed_type_names)] }.must_equal expected
798
802
  # end
799
803
  # Permissions.with_user(@visitor) do
800
804
  expected = [
801
805
  ["default_level", []]
802
806
  ]
803
- C.export(@visitor)[:boxes].map { |b| [b[:name], b[:allowed_types]] }.must_equal expected
807
+ C.export(@visitor)[:boxes].map { |b| [b[:name], b[:allowed_types].map(&allowed_type_names)] }.must_equal expected
804
808
  # end
805
809
  # Permissions.with_user(@editor) do
806
810
  expected = [
@@ -808,7 +812,7 @@ describe "Permissions" do
808
812
  ["mixed_level", []],
809
813
  ["default_level", ["C"]]
810
814
  ]
811
- C.export(@editor)[:boxes].map { |b| [b[:name], b[:allowed_types]] }.must_equal expected
815
+ C.export(@editor)[:boxes].map { |b| [b[:name], b[:allowed_types].map(&allowed_type_names)] }.must_equal expected
812
816
  # end
813
817
  # Permissions.with_user(@admin) do
814
818
  expected = [
@@ -817,7 +821,7 @@ describe "Permissions" do
817
821
  ["mixed_level", []],
818
822
  ["default_level", ["C"]]
819
823
  ]
820
- C.export(@admin)[:boxes].map { |b| [b[:name], b[:allowed_types]] }.must_equal expected
824
+ C.export(@admin)[:boxes].map { |b| [b[:name], b[:allowed_types].map(&allowed_type_names)] }.must_equal expected
821
825
  # end
822
826
  end
823
827
 
@@ -890,7 +894,7 @@ describe "Permissions" do
890
894
  end
891
895
 
892
896
  it "determine what fields are visible in the exoported schema" do
893
- schema = Site.schema.export(@editor)
897
+ schema = @site.schema.export(@editor)
894
898
  c_schema = schema["C"]
895
899
  c_schema[:fields].map { |f| f[:name] }.must_equal %w(editor_level mixed_level default_level)
896
900
  c_schema[:boxes].map { |b| b[:name] }.must_equal %w(editor_level mixed_level default_level)
@@ -32,15 +32,15 @@ describe "Plugins" do
32
32
  end
33
33
 
34
34
  def app
35
- Spontaneous::Rack.application
35
+ Spontaneous::Rack.application(@site)
36
36
  end
37
37
 
38
38
 
39
39
  before do
40
- S::Site.background_mode = :immediate
41
40
  S::State.delete
42
41
  Content.delete
43
42
  @site = Spontaneous.instance
43
+ @site.background_mode = :immediate
44
44
  page = ::Page.new
45
45
  page.save
46
46
 
@@ -91,7 +91,7 @@ describe "Plugins" do
91
91
  Content.delete_revision(1) rescue nil
92
92
 
93
93
  Spontaneous.logger.silent! {
94
- S::Site.publish_all
94
+ @site.publish_all
95
95
  }
96
96
  end
97
97
 
@@ -89,6 +89,13 @@ describe "PrototypeSet" do
89
89
  lambda { @set.nine }.must_raise(NoMethodError)
90
90
  end
91
91
 
92
+ it "uses the given block to set default values" do
93
+ set = Spontaneous::Collections::PrototypeSet.new { |set, key| set[key] = key.to_s.upcase }
94
+ set.key?(:one).must_equal false
95
+ set[:one].must_equal "ONE"
96
+ set.keys.must_equal [:one]
97
+ end
98
+
92
99
  describe "with superset" do
93
100
  before do
94
101
  @superset = @set.dup
@@ -96,7 +103,7 @@ describe "PrototypeSet" do
96
103
  @superset.order = [:three, :one, :two]
97
104
  @super = Super.new
98
105
  @super.prototypes = @superset
99
- @set = Spontaneous::Collections::PrototypeSet.new(@super, :prototypes)
106
+ @set = Spontaneous::Collections::PrototypeSet.new(@super, :prototypes) { |set, key| set[key] = key.to_s.upcase }
100
107
  @four = "Four"
101
108
  @five = "Five"
102
109
  @four.stubs(:schema_id).returns("four_id")
@@ -21,7 +21,8 @@ describe "Publishing" do
21
21
  stub_time(@now)
22
22
 
23
23
  @site = setup_site(site_root)
24
- Site.background_mode = :immediate
24
+ @site.background_mode = :immediate
25
+ @output_store = @site.output_store(:Memory)
25
26
 
26
27
  Content.delete
27
28
 
@@ -57,7 +58,7 @@ describe "Publishing" do
57
58
 
58
59
  it "delete any conflicting revision tables" do
59
60
  S::Publishing::Revision.create(Content, 3)
60
- S::Site.publish_all
61
+ @site.publish_all
61
62
  end
62
63
 
63
64
  it "issue a publish_all if passed page id list including all pages (in any order)" do
@@ -66,19 +67,19 @@ describe "Publishing" do
66
67
 
67
68
  it "publish all" do
68
69
  Content.expects(:publish).with(@revision, nil)
69
- S::Site.publish_all
70
+ @site.publish_all
70
71
  end
71
72
 
72
73
  it "record date and time of publish" do
73
74
  Content.expects(:publish).with(@revision, nil)
74
75
  S::PublishedRevision.expects(:create).with(:revision => @revision, :published_at => @now)
75
- S::Site.publish_all
76
+ @site.publish_all
76
77
  end
77
78
 
78
79
  it "bump revision after a publish" do
79
- S::Site.publish_all
80
- S::Site.revision.must_equal @revision + 1
81
- S::Site.published_revision.must_equal @revision
80
+ @site.publish_all
81
+ @site.revision.must_equal @revision + 1
82
+ @site.published_revision.must_equal @revision
82
83
  end
83
84
 
84
85
  it "not delete scheduled changes after an exception during publish" do
@@ -86,23 +87,22 @@ describe "Publishing" do
86
87
  end
87
88
 
88
89
  it "set Site.pending_revision before publishing" do
89
- Content.expects(:publish).with(@revision, nil) { Site.pending_revision == @revision }
90
- Site.publish_all
90
+ Content.expects(:publish).with(@revision, nil) { @site.pending_revision == @revision }
91
+ @site.publish_all
91
92
  end
92
93
 
93
94
  it "reset Site.pending_revision after publishing" do
94
- Site.publish_all
95
- Site.pending_revision.must_be_nil
95
+ @site.publish_all
96
+ @site.pending_revision.must_be_nil
96
97
  end
97
98
 
98
99
  it "not update first_published or last_published if rendering fails" do
99
100
  c = Content.create
100
101
  c.first_published_at.must_be_nil
101
- Spontaneous::Site.expects(:pages).returns([c])
102
+ @site.expects(:pages).returns([c])
102
103
  # c.expects(:render).raises(Exception)
103
104
  begin
104
- silence_logger { Site.publish_all }
105
- # Site.publish_all
105
+ silence_logger { @site.publish_all }
106
106
  rescue Exception; end
107
107
  c.reload
108
108
  Content.with_editable do
@@ -111,26 +111,39 @@ describe "Publishing" do
111
111
  end
112
112
 
113
113
  it "clean up state on publishing failure" do
114
- Site.pending_revision.must_be_nil
114
+ @site.pending_revision.must_be_nil
115
115
  refute Content.revision_exists?(@revision)
116
116
  # don't like peeking into implementation here but don't know how else
117
117
  # to simulate the right error
118
118
  root = Page.create()
119
- Spontaneous::Site.expects(:pages).returns([root])
119
+ @site.expects(:pages).returns([root])
120
120
  output = root.output(:html)
121
121
  output.expects(:render_using).raises(Exception)
122
122
  root.expects(:outputs).at_least_once.returns([output])
123
+ revision_store = @output_store.revision(@revision)
124
+ @output_store.expects(:revision).with(@revision).at_least_once.returns(revision_store)
125
+ transaction = []
126
+ revision_store.expects(:delete)
127
+ revision_store.expects(:transaction).returns(transaction)
128
+ transaction.expects(:rollback)
123
129
  begin
124
- silence_logger { Site.publish_all }
130
+ silence_logger { @site.publish_all }
125
131
  rescue Exception; end
126
- Site.pending_revision.must_be_nil
132
+ @site.pending_revision.must_be_nil
133
+ @output_store.revisions.must_equal []
127
134
  refute Content.revision_exists?(@revision)
128
135
  begin
129
- silence_logger { Site.publish_pages([change1]) }
136
+ silence_logger { @site.publish_pages([change1]) }
130
137
  rescue Exception; end
131
- Site.pending_revision.must_be_nil
138
+ @site.pending_revision.must_be_nil
132
139
  refute Content.revision_exists?(@revision)
133
140
  end
141
+
142
+ it "resets the must_publish_all flag after a successful publish" do
143
+ @site.must_publish_all!
144
+ @site.publish_all
145
+ @site.must_publish_all?.must_equal false
146
+ end
134
147
  end
135
148
 
136
149
 
@@ -141,7 +154,7 @@ describe "Publishing" do
141
154
  Content.delete
142
155
  S::State.delete
143
156
  S::State.create(:revision => @revision, :published_revision => 2)
144
- S::Site.revision.must_equal @revision
157
+ @site.revision.must_equal @revision
145
158
 
146
159
 
147
160
  class ::PublishablePage < Page; end
@@ -154,7 +167,9 @@ describe "Publishing" do
154
167
  DynamicPublishablePage.layout :"static"
155
168
  DynamicPublishablePage.layout :"dynamic"
156
169
 
157
- DynamicPublishablePage.request { show "/about" }
170
+ DynamicPublishablePage.controller do
171
+ get { show "/about" }
172
+ end
158
173
 
159
174
  @home = PublishablePage.create(:title => 'Home')
160
175
  @home.layout = :"dynamic"
@@ -175,7 +190,8 @@ describe "Publishing" do
175
190
  @blog.box1 << @post3
176
191
  @pages = [@home, @about, @blog, @news, @post1, @post2, @post3]
177
192
  @pages.each { |p| p.save }
178
- Site.publish_all
193
+ @site.publish_all
194
+ @template_revision = @output_store.revision(2)
179
195
  end
180
196
 
181
197
  after do
@@ -187,10 +203,6 @@ describe "Publishing" do
187
203
  Object.send(:remove_const, :DynamicPublishablePage) rescue nil
188
204
  end
189
205
 
190
- it "put its files into a numbered revision directory" do
191
- Spontaneous.revision_dir(2).must_equal Pathname.new(@site.root / 'cache/revisions' / "00002").realpath.to_s
192
- end
193
-
194
206
  it "symlink the latest revision to 'current'" do
195
207
  revision_dir = @site.revision_root / "00002"
196
208
  current_dir = @site.revision_root / "current"
@@ -200,30 +212,29 @@ describe "Publishing" do
200
212
  end
201
213
 
202
214
  it "have access to the current revision within the templates" do
203
- revision_dir = @site.revision_root / "00002"
204
- File.read(revision_dir / "static/about.html").must_equal "Page: 'About' 2\n"
215
+ @template_revision.static_template(@about.output(:html)).read.must_equal "Page: 'About' 2\n"
205
216
  end
206
217
 
207
218
  it "produce rendered versions of each page" do
208
219
  revision_dir = @site.revision_root / "00002"
209
- file = result = nil
220
+ file = result = expected = nil
210
221
  @pages.each do |page|
222
+ output = page.output(:html)
211
223
  case page.slug
212
224
  when "" # root is a dynamic page with no request handler
213
- file = revision_dir / "dynamic/index.html.cut"
214
- result = "Page: '#{page.title}' {{Time.now.to_i}}\n"
225
+ expected = "Page: '#{page.title}' {{Time.now.to_i}}\n"
226
+ result = @template_revision.dynamic_template(output)
215
227
  when "news" # news produces a static template but has a request handler
216
- file = revision_dir / "protected/news.html"
217
- result = "Page: 'News' 2\n"
228
+ expected = "Page: 'News' 2\n"
229
+ result = @template_revision.static_template(output)
218
230
  when "contact" # contact is both dynamic and has a request handler
219
- file = revision_dir / "dynamic/contact.html.cut"
220
- result = "Page: 'Contact' {{Time.now.to_i}}\n"
231
+ expected = "Page: 'Contact' {{Time.now.to_i}}\n"
232
+ result = @template_revision.dynamic_template(output)
221
233
  else # the other pages are static
222
- file = revision_dir / "static#{page.path}.html"
223
- result = "Page: '#{page.title}' 2\n"
234
+ expected = "Page: '#{page.title}' 2\n"
235
+ result = @template_revision.static_template(output)
224
236
  end
225
- assert File.exists?(file), "File '#{file}' should exist"
226
- File.read(file).must_equal result
237
+ assert_equal expected, result.read
227
238
  end
228
239
  revision_dir = @site.revision_root / "00002"
229
240
  Dir[S.root / "public/**/*"].each do |public_file|
@@ -248,20 +259,22 @@ describe "Publishing" do
248
259
  it "transparently support previously unknown formats by assuming a simple HTML like rendering model" do
249
260
  PublishablePage.add_output :rtf
250
261
  Content.delete_revision(@revision+1)
251
- Site.publish_all
252
- File.read("#{@site.revision_root}/00003/static/index.rtf").must_equal "RICH!\n"
262
+ @site.publish_all
263
+ template_revision = @output_store.revision(@revision+1)
264
+ render = template_revision.static_template(@home.output(:rtf))
265
+ render.read.must_equal "RICH!\n"
253
266
  end
254
267
 
255
268
  it "respect a format's #dynamic? setting when deciding a rendered templates location" do
256
269
  PublishablePage.add_output :rtf, :dynamic => true
257
270
  Content.delete_revision(@revision+1)
258
- Site.publish_all
259
- File.read("#{@site.revision_root}/00003/dynamic/index.rtf.cut").must_equal "RICH!\n"
271
+ @site.publish_all
272
+ @output_store.revision(@revision + 1).dynamic_template(@home.output(:rtf)).read.must_equal "RICH!\n"
260
273
  end
261
274
 
262
275
  it "run the content revision cleanup task after the revision is live" do
263
276
  Content.expects(:cleanup_revisions).with(@revision+1, 8)
264
- Site.publish_all
277
+ @site.publish_all
265
278
  end
266
279
 
267
280
  describe "hooks & triggers" do
@@ -270,32 +283,32 @@ describe "Publishing" do
270
283
  publish1.expects(:finished).with(@revision+1)
271
284
  publish2 = mock
272
285
  publish2.expects(:finished)
273
- Site.after_publish do |revision|
286
+ @site.after_publish do |revision|
274
287
  publish1.finished(revision)
275
288
  end
276
- Site.after_publish do
289
+ @site.after_publish do
277
290
  publish2.finished
278
291
  end
279
292
  Content.delete_revision(@revision+1)
280
- Site.publish_all
281
- Site.published_revision.must_equal @revision+1
293
+ @site.publish_all
294
+ @site.published_revision.must_equal @revision+1
282
295
  end
283
296
 
284
297
  it "abort publish if hook raises error" do
285
298
  published_revision = @revision+1
286
- Site.pending_revision.must_be_nil
299
+ @site.pending_revision.must_be_nil
287
300
  refute Content.revision_exists?(published_revision)
288
301
 
289
- Site.after_publish do |revision|
302
+ @site.after_publish do |revision|
290
303
  raise "Boom"
291
304
  end
292
305
 
293
306
  begin
294
- silence_logger { Site.publish_all }
307
+ silence_logger { @site.publish_all }
295
308
  rescue Exception; end
296
309
 
297
- Site.pending_revision.must_be_nil
298
- Site.published_revision.must_equal @revision
310
+ @site.pending_revision.must_be_nil
311
+ @site.published_revision.must_equal @revision
299
312
  refute Content.revision_exists?(published_revision)
300
313
  S::PublishedRevision.first(:revision => published_revision).must_be_nil
301
314
  previous_root = Spontaneous.revision_dir(@revision)
@@ -35,9 +35,19 @@ describe "Render" do
35
35
  end
36
36
  end
37
37
  field :description do
38
+ def render(format = :html, locals = {}, parent_context = nil)
39
+ case format
40
+ when :pdf
41
+ to_pdf
42
+ else
43
+ super
44
+ end
45
+ end
46
+
38
47
  def to_pdf
39
48
  "{#{value}}"
40
49
  end
50
+
41
51
  def to_epub
42
52
  to_html
43
53
  end
@@ -68,8 +78,7 @@ describe "Render" do
68
78
 
69
79
  @root.sections2.entries.last.set_position(0)
70
80
  @root.save.reload
71
- @renderer = Spontaneous::Output::Template::PublishRenderer.new
72
- Spontaneous::Output.renderer = @renderer
81
+ @renderer = Spontaneous::Output::Template::PublishRenderer.new(@site)
73
82
  end
74
83
 
75
84
  after do
@@ -82,9 +91,9 @@ describe "Render" do
82
91
  end
83
92
 
84
93
  it "use a cache for the site root" do
85
- a = @renderer.render_string('#{root.object_id} #{root.object_id}', @page.output(:html), {})
86
- a.wont_equal "#{nil.object_id} #{nil.object_id}"
87
- a.split.uniq.length.must_equal 1
94
+ a = @renderer.render_string('#{root.object_id} #{root.object_id}', @page.output(:html), {})
95
+ a.wont_equal "#{nil.object_id} #{nil.object_id}"
96
+ a.split.uniq.length.must_equal 1
88
97
  end
89
98
 
90
99
  it "uses a cache for site pages" do
@@ -98,27 +107,27 @@ describe "Render" do
98
107
  template = '%%{ navigation(%s) do |section, active| }${section.title}/${active} %%{ end }'
99
108
  a = @renderer.render_string(template % "", @section1.output(:html), {})
100
109
  a.must_equal "Section 1/true Section 2/false Section 4/false Section 3/false "
101
- a = @renderer.render_string(template % "1", @section2.output(:html), {})
110
+ a = @renderer.render_string(template % "depth: 1", @section2.output(:html), {})
102
111
  a.must_equal "Section 1/false Section 2/true Section 4/false Section 3/false "
103
- a = @renderer.render_string(template % ":section", @section1.output(:html), {})
112
+ a = @renderer.render_string(template % "depth: :section", @section1.output(:html), {})
104
113
  a.must_equal "Section 1/true Section 2/false Section 4/false Section 3/false "
105
114
  end
106
115
 
107
116
  it "use a cache for navigation pages" do
108
117
  a = b = c = nil
109
118
  template = '%{ navigation do |section, active| }${section.object_id} %{ end }'
110
- renderer = Spontaneous::Output::Template::PreviewRenderer.new
119
+ renderer = Spontaneous::Output::Template::PreviewRenderer.new(@site)
111
120
  a = renderer.render_string(template, ::Content[@section1.id].output(:html), {}).strip
112
121
  b = renderer.render_string(template, ::Content[@section1.id].output(:html), {}).strip
113
122
  a.wont_equal b
114
123
 
115
- renderer = Spontaneous::Output::Template::PublishRenderer.new
124
+ renderer = Spontaneous::Output::Template::PublishRenderer.new(@site)
116
125
  template = '%{ navigation do |section, active| }${section.object_id} %{ end }'
117
126
  a = renderer.render_string(template, ::Content[@section1.id].output(:html), {}).strip
118
127
  b = renderer.render_string(template, ::Content[@section1.id].output(:html), {}).strip
119
128
  a.must_equal b
120
129
 
121
- renderer = Spontaneous::Output::Template::PublishRenderer.new
130
+ renderer = Spontaneous::Output::Template::PublishRenderer.new(@site)
122
131
  template = '%{ navigation do |section, active| }${section.object_id} %{ end }'
123
132
  c = renderer.render_string(template, ::Content[@section1.id].output(:html), {}).strip
124
133
  a.wont_equal c
@@ -222,8 +231,8 @@ describe "Render" do
222
231
  end
223
232
  @page.image = "/photo.jpg"
224
233
  output = @page.render
225
- output.must_match /width=['"]10['"]/
226
- output.must_match /height=['"]50['"]/
234
+ output.must_match /width=['"]10["']/
235
+ output.must_match /height=["']50['"]/
227
236
  end
228
237
 
229
238
  end
@@ -388,7 +397,7 @@ describe "Render" do
388
397
  it "use their default page style when accessed directly" do
389
398
  @page = PageClass[@page.id]
390
399
  @page.layout.must_equal PageClass.default_layout
391
- assert_correct_template(@parent, template_root / 'layouts/page_style')
400
+ assert_correct_template(@parent, template_root / 'layouts/page_style', @renderer)
392
401
  @page.render.must_equal "<html></html>\n"
393
402
  end
394
403
 
@@ -398,7 +407,7 @@ describe "Render" do
398
407
  end
399
408
 
400
409
  it "render using the inline style" do
401
- assert_correct_template(@parent.contents.first, template_root / 'page_class/inline_style')
410
+ assert_correct_template(@parent.contents.first, template_root / 'page_class/inline_style', @renderer)
402
411
  @parent.contents.first.render.must_equal "Child\n"
403
412
  @parent.things.render.must_equal "Child\n"
404
413
  @parent.render.must_equal "<html>Child\n</html>\n"
@@ -450,8 +459,7 @@ describe "Render" do
450
459
 
451
460
  describe "Preview render" do
452
461
  before do
453
- @renderer = Spontaneous::Output::Template::PreviewRenderer.new
454
- Spontaneous::Output.renderer = @renderer
462
+ @renderer = Spontaneous::Output::Template::PreviewRenderer.new(@site)
455
463
  PreviewRender.layout :preview_render
456
464
  end
457
465
 
@@ -482,13 +490,12 @@ describe "Render" do
482
490
  end
483
491
  describe "Request rendering" do
484
492
  before do
485
- @renderer = Spontaneous::Output::Template::PreviewRenderer.new
486
- Spontaneous::Output.renderer = @renderer
493
+ @renderer = Spontaneous::Output::Template::PreviewRenderer.new(@site)
487
494
  PreviewRender.layout :params
488
495
  end
489
496
 
490
497
  it "pass on passed params" do
491
- result = @page.render({
498
+ result = @page.render_using(@renderer, :html, {
492
499
  :welcome => "hello"
493
500
  })
494
501
  result.must_equal "PAGE hello\n"
@@ -498,8 +505,7 @@ describe "Render" do
498
505
 
499
506
  describe "entry parameters" do
500
507
  before do
501
- @renderer = Spontaneous::Output::Template::PreviewRenderer.new
502
- Spontaneous::Output.renderer = @renderer
508
+ @renderer = Spontaneous::Output::Template::PreviewRenderer.new(@site)
503
509
  PreviewRender.layout :entries
504
510
  @first = PreviewRender.new(:title => "first")
505
511
  @second = PreviewRender.new(:title => "second")
@@ -522,8 +528,7 @@ describe "Render" do
522
528
  FileUtils.mkdir_p(@temp_template_root / "layouts")
523
529
  @site.paths.add(:templates, @temp_template_root)
524
530
 
525
- @renderer = Spontaneous::Output::Template::PublishRenderer.new(true)
526
- Spontaneous::Output.renderer = @renderer
531
+ @renderer = Spontaneous::Output::Template::PublishRenderer.new(@site, true)
527
532
 
528
533
  @template_path = @temp_template_root / "layouts/standard.html.cut"
529
534
  @compiled_path = @temp_template_root / "layouts/standard.html.rb"
@@ -542,27 +547,75 @@ describe "Render" do
542
547
  @first.save
543
548
  end
544
549
 
545
- it "ignore compiled template file if it is older than the template" do
546
- @first.render.must_equal "compiled"
547
- File.open(@temp_template_root / "layouts/standard.html.cut", "w") do |t|
548
- t.write("updated template")
550
+ # Disabled pending decision about the best way to optimize templates
551
+ # in the case of this example, where we are optimizing the first render
552
+ # of a site template (not a rendered page) I'm not sure that it's worth it
553
+ # at all...
554
+ it "ignore compiled template file if it is older than the template"
555
+ # @first.render_using(@renderer).must_equal "compiled"
556
+ # File.open(@temp_template_root / "layouts/standard.html.cut", "w") do |t|
557
+ # t.write("updated template")
558
+ # end
559
+ # later = Time.now + 1000
560
+ # File.utime(later, later, @template_path)
561
+ # template_mtime = File.mtime(@template_path)
562
+ # compiled_mtime = File.mtime(@compiled_path)
563
+ # assert template_mtime > compiled_mtime, "Template file should register as newer"
564
+ # # Need to use a new renderer because the existing one will have cached the compiled template
565
+ # @renderer = Spontaneous::Output::Template::PublishRenderer.new(@site)
566
+ # @first.render.must_equal "updated template"
567
+ # end
568
+ end
569
+
570
+ describe "PublishedRenderer" do
571
+ before do
572
+ @site.background_mode = :immediate
573
+ @site.output_store :Memory
574
+
575
+ ::Content.delete
576
+ ::Content.delete_revision(1) rescue nil
577
+ @renderer = Spontaneous::Output::Template::PublishedRenderer.new(@site, 1)
578
+ Page.box :other
579
+ class ::DynamicPage < Page
580
+ layout(:html) { "${path}.${ __format }:{{ something }}"}
549
581
  end
550
- later = Time.now + 1000
551
- File.utime(later, later, @template_path)
552
- template_mtime = File.mtime(@template_path)
553
- compiled_mtime = File.mtime(@compiled_path)
554
- assert template_mtime > compiled_mtime, "Template file should register as newer"
555
- # Need to use a new renderer because the existing one will have cached the compiled template
556
- @renderer = Spontaneous::Output::Template::PublishRenderer.new
557
- Spontaneous::Output.renderer = @renderer
558
- @first.render.must_equal "updated template"
582
+ class ::StaticPage < Page
583
+ layout(:html) { "${ path }.${ __format }"}
584
+ end
585
+
586
+ @root = Page.create
587
+ assert @root.is_root?
588
+
589
+ @dynamic = DynamicPage.new(slug: "dynamic", uid: "dynamic")
590
+ @static = StaticPage.new(slug: "static", uid: "static")
591
+ @root.other << @dynamic
592
+ @root.other << @static
593
+
594
+ [@root, @dynamic, @static].each(&:save)
595
+
596
+ @site.publish_all
597
+ end
598
+
599
+ after do
600
+ Object.send :remove_const, :StaticPage
601
+ Object.send :remove_const, :DynamicPage
602
+ ::Content.delete
603
+ end
604
+
605
+ it "should render dynamic pages from the template store xxx" do
606
+ result = @renderer.render!(@dynamic.output(:html), { something: "something here" }, nil)
607
+ result.must_equal "/dynamic.html:something here"
608
+ end
609
+
610
+ it "should render static pages from the template store xxx" do
611
+ result = @renderer.render!(@static.output(:html), { something: "something here" }, nil)
612
+ result.read.must_equal "/static.html"
559
613
  end
560
614
  end
561
615
 
562
616
  describe "variables in render command" do
563
617
  before do
564
- @renderer = Spontaneous::Output::Template::PublishRenderer.new
565
- Spontaneous::Output.renderer = @renderer
618
+ @renderer = Spontaneous::Output::Template::PublishRenderer.new(@site)
566
619
 
567
620
  PreviewRender.layout :variables
568
621
  PreviewRender.style :variables