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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +39 -0
- data/Gemfile +11 -6
- data/Readme.markdown +136 -69
- data/application/css/core.css.scss +27 -7
- data/application/css/editing.css.scss +4 -26
- data/application/css/schema_error.css.scss +22 -0
- data/application/js/content.js +11 -3
- data/application/js/edit_panel.js +1 -4
- data/application/js/field/file.js +17 -0
- data/application/js/field/image.js +30 -21
- data/application/js/field/string.js +4 -1
- data/application/js/field_preview.js +21 -16
- data/application/js/publish.js +6 -6
- data/application/js/types.js +5 -13
- data/application/js/views.js +2 -2
- data/application/js/views/box_view.js +3 -2
- data/application/js/views/page_piece_view.js +1 -1
- data/application/js/views/piece_view.js +1 -1
- data/application/views/schema_modification_error.html.erb +13 -3
- data/db/migrations/20131104101935_site_must_publish_all.rb +14 -0
- data/lib/spontaneous.rb +0 -1
- data/lib/spontaneous/box_style.rb +15 -9
- data/lib/spontaneous/capistrano/deploy.rb +13 -1
- data/lib/spontaneous/change.rb +11 -13
- data/lib/spontaneous/cli.rb +5 -2
- data/lib/spontaneous/cli/assets.rb +7 -1
- data/lib/spontaneous/cli/console.rb +7 -1
- data/lib/spontaneous/cli/content.rb +35 -0
- data/lib/spontaneous/cli/fields.rb +3 -2
- data/lib/spontaneous/cli/generate.rb +5 -2
- data/lib/spontaneous/cli/server.rb +12 -8
- data/lib/spontaneous/cli/site.rb +12 -12
- data/lib/spontaneous/cli/user.rb +28 -14
- data/lib/spontaneous/collections/box_set.rb +4 -4
- data/lib/spontaneous/collections/field_set.rb +4 -4
- data/lib/spontaneous/collections/prototype_set.rb +12 -4
- data/lib/spontaneous/data_mapper.rb +11 -7
- data/lib/spontaneous/data_mapper/content_model.rb +8 -0
- data/lib/spontaneous/data_mapper/content_model/associations.rb +1 -1
- data/lib/spontaneous/data_mapper/dataset.rb +14 -2
- data/lib/spontaneous/data_mapper/scope.rb +33 -13
- data/lib/spontaneous/facet.rb +4 -0
- data/lib/spontaneous/field.rb +12 -12
- data/lib/spontaneous/field/base.rb +27 -22
- data/lib/spontaneous/field/boolean.rb +4 -4
- data/lib/spontaneous/field/date.rb +2 -2
- data/lib/spontaneous/field/file.rb +24 -18
- data/lib/spontaneous/field/html.rb +1 -1
- data/lib/spontaneous/field/image.rb +6 -19
- data/lib/spontaneous/field/location.rb +1 -1
- data/lib/spontaneous/field/long_string.rb +3 -3
- data/lib/spontaneous/field/markdown.rb +3 -3
- data/lib/spontaneous/field/select.rb +2 -2
- data/lib/spontaneous/field/string.rb +2 -2
- data/lib/spontaneous/field/tags.rb +2 -2
- data/lib/spontaneous/field/update.rb +21 -20
- data/lib/spontaneous/field/webvideo.rb +6 -6
- data/lib/spontaneous/field/webvideo/fallback.rb +2 -2
- data/lib/spontaneous/field/webvideo/vimeo.rb +7 -7
- data/lib/spontaneous/generators/site.rb +2 -2
- data/lib/spontaneous/generators/site/Gemfile.tt +5 -1
- data/lib/spontaneous/layout.rb +2 -2
- data/lib/spontaneous/media.rb +1 -0
- data/lib/spontaneous/media/file.rb +6 -5
- data/lib/spontaneous/media/image/attributes.rb +4 -0
- data/lib/spontaneous/media/image/renderable.rb +4 -4
- data/lib/spontaneous/media/store.rb +22 -0
- data/lib/spontaneous/{storage → media/store}/backend.rb +1 -1
- data/lib/spontaneous/{storage → media/store}/cloud.rb +1 -1
- data/lib/spontaneous/{storage → media/store}/local.rb +1 -1
- data/lib/spontaneous/media/temp_file.rb +1 -1
- data/lib/spontaneous/model.rb +10 -7
- data/lib/spontaneous/model/action.rb +7 -0
- data/lib/spontaneous/model/action/clean.rb +87 -0
- data/lib/spontaneous/model/box/allowed_types.rb +15 -1
- data/lib/spontaneous/model/core.rb +10 -0
- data/lib/spontaneous/model/core/aliases.rb +1 -1
- data/lib/spontaneous/model/core/content_groups.rb +1 -1
- data/lib/spontaneous/model/core/fields.rb +1 -1
- data/lib/spontaneous/model/core/modifications.rb +2 -2
- data/lib/spontaneous/model/core/page_search.rb +4 -0
- data/lib/spontaneous/model/core/publishing.rb +4 -17
- data/lib/spontaneous/model/core/render.rb +4 -4
- data/lib/spontaneous/model/core/styles.rb +2 -2
- data/lib/spontaneous/model/core/visibility.rb +6 -2
- data/lib/spontaneous/model/page.rb +6 -2
- data/lib/spontaneous/model/page/controllers.rb +55 -17
- data/lib/spontaneous/model/page/formats.rb +12 -7
- data/lib/spontaneous/model/page/layouts.rb +2 -2
- data/lib/spontaneous/model/page/locks.rb +4 -1
- data/lib/spontaneous/model/page/page_tree.rb +40 -6
- data/lib/spontaneous/output.rb +14 -52
- data/lib/spontaneous/output/context.rb +11 -39
- data/lib/spontaneous/output/context/navigation.rb +31 -0
- data/lib/spontaneous/output/format.rb +15 -19
- data/lib/spontaneous/output/renderable.rb +99 -0
- data/lib/spontaneous/output/store.rb +24 -0
- data/lib/spontaneous/output/store/backend.rb +52 -0
- data/lib/spontaneous/output/store/file.rb +77 -0
- data/lib/spontaneous/output/store/moneta.rb +117 -0
- data/lib/spontaneous/output/store/revision.rb +34 -0
- data/lib/spontaneous/output/store/store.rb +15 -0
- data/lib/spontaneous/output/store/transaction.rb +44 -0
- data/lib/spontaneous/output/template/engine.rb +17 -7
- data/lib/spontaneous/output/template/renderer.rb +66 -40
- data/lib/spontaneous/page_lock.rb +5 -7
- data/lib/spontaneous/page_piece.rb +2 -2
- data/lib/spontaneous/permissions/user.rb +14 -7
- data/lib/spontaneous/plugins/application/features.rb +8 -4
- data/lib/spontaneous/plugins/application/state.rb +12 -6
- data/lib/spontaneous/prototypes/box_prototype.rb +9 -10
- data/lib/spontaneous/prototypes/field_prototype.rb +66 -15
- data/lib/spontaneous/publishing/immediate.rb +30 -26
- data/lib/spontaneous/rack.rb +12 -7
- data/lib/spontaneous/rack/back.rb +43 -37
- data/lib/spontaneous/rack/back/base.rb +4 -4
- data/lib/spontaneous/rack/back/changes.rb +2 -2
- data/lib/spontaneous/rack/back/file.rb +16 -24
- data/lib/spontaneous/rack/back/map.rb +5 -5
- data/lib/spontaneous/rack/back/preview.rb +3 -4
- data/lib/spontaneous/rack/back/schema.rb +1 -1
- data/lib/spontaneous/rack/back/site.rb +6 -7
- data/lib/spontaneous/rack/front.rb +19 -16
- data/lib/spontaneous/rack/middleware/authenticate.rb +3 -3
- data/lib/spontaneous/rack/middleware/reloader.rb +3 -2
- data/lib/spontaneous/rack/middleware/scope.rb +25 -19
- data/lib/spontaneous/rack/page_controller.rb +164 -13
- data/lib/spontaneous/rack/public.rb +23 -62
- data/lib/spontaneous/rack/static.rb +2 -3
- data/lib/spontaneous/schema.rb +27 -8
- data/lib/spontaneous/schema/schema_modification.rb +9 -1
- data/lib/spontaneous/schema/uid.rb +2 -2
- data/lib/spontaneous/schema/uid_map.rb +3 -2
- data/lib/spontaneous/search/database.rb +2 -2
- data/lib/spontaneous/search/field.rb +5 -3
- data/lib/spontaneous/search/index.rb +12 -7
- data/lib/spontaneous/search/results.rb +5 -3
- data/lib/spontaneous/server.rb +2 -2
- data/lib/spontaneous/site.rb +10 -3
- data/lib/spontaneous/site/features.rb +26 -6
- data/lib/spontaneous/site/helpers.rb +9 -12
- data/lib/spontaneous/site/level.rb +7 -9
- data/lib/spontaneous/site/map.rb +9 -11
- data/lib/spontaneous/site/paths.rb +5 -5
- data/lib/spontaneous/site/publishing.rb +83 -80
- data/lib/spontaneous/site/schema.rb +1 -7
- data/lib/spontaneous/site/search.rb +8 -18
- data/lib/spontaneous/site/selectors.rb +60 -54
- data/lib/spontaneous/site/state.rb +36 -30
- data/lib/spontaneous/site/storage.rb +10 -16
- data/lib/spontaneous/state.rb +8 -0
- data/lib/spontaneous/style.rb +32 -33
- data/lib/spontaneous/version.rb +1 -1
- data/spontaneous.gemspec +22 -21
- data/test/fixtures/public/templates/layouts/default.html.cut +1 -1
- data/test/fixtures/public/templates/layouts/default.pdf.cut +1 -1
- data/test/fixtures/public/templates/layouts/default.rss.cut +1 -1
- data/test/fixtures/search/config/indexes.rb +1 -1
- data/test/fixtures/serialisation/class_hash.yaml.erb +13 -1
- data/test/fixtures/serialisation/root_hash.yaml.erb +10 -0
- data/test/functional/test_application.rb +20 -24
- data/test/functional/test_back.rb +26 -27
- data/test/functional/test_cli.rb +146 -0
- data/test/functional/test_front.rb +287 -216
- data/test/functional/test_user_manager.rb +1 -1
- data/test/test_helper.rb +15 -11
- data/test/unit/test_alias.rb +32 -25
- data/test/unit/test_asset_bundler.rb +1 -1
- data/test/unit/test_assets.rb +34 -33
- data/test/unit/test_authentication.rb +1 -1
- data/test/unit/test_boxes.rb +16 -2
- data/test/unit/test_changesets.rb +23 -11
- data/test/unit/test_content.rb +15 -0
- data/test/unit/test_context.rb +139 -0
- data/test/unit/test_controllers.rb +374 -0
- data/test/{experimental → unit}/test_crypt.rb +0 -0
- data/test/unit/test_datamapper.rb +260 -237
- data/test/unit/test_datamapper_content.rb +42 -12
- data/test/{experimental → unit}/test_features.rb +85 -3
- data/test/unit/test_fields.rb +117 -42
- data/test/unit/test_formats.rb +11 -1
- data/test/unit/test_generators.rb +2 -2
- data/test/unit/test_helpers.rb +7 -8
- data/test/unit/test_images.rb +39 -2
- data/test/unit/test_layouts.rb +14 -12
- data/test/unit/test_media.rb +32 -23
- data/test/unit/test_output_store.rb +342 -0
- data/test/unit/test_page.rb +8 -1
- data/test/unit/test_permissions.rb +11 -7
- data/test/unit/test_plugins.rb +3 -3
- data/test/unit/test_prototype_set.rb +8 -1
- data/test/unit/test_publishing.rb +67 -54
- data/test/unit/test_render.rb +91 -38
- data/test/unit/test_revisions.rb +4 -4
- data/test/unit/test_schema.rb +109 -84
- data/test/unit/test_search.rb +42 -42
- data/test/unit/test_serialisation.rb +3 -2
- data/test/unit/test_site.rb +39 -27
- data/test/unit/test_storage.rb +9 -6
- data/test/unit/test_styles.rb +25 -32
- data/test/unit/test_templates.rb +8 -4
- metadata +89 -54
- data/lib/spontaneous/model/page/request.rb +0 -105
- data/lib/spontaneous/storage.rb +0 -22
data/test/unit/test_page.rb
CHANGED
@@ -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
|
-
|
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::
|
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 =
|
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)
|
data/test/unit/test_plugins.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
76
|
+
@site.publish_all
|
76
77
|
end
|
77
78
|
|
78
79
|
it "bump revision after a publish" do
|
79
|
-
|
80
|
-
|
81
|
-
|
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) {
|
90
|
-
|
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
|
-
|
95
|
-
|
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
|
-
|
102
|
+
@site.expects(:pages).returns([c])
|
102
103
|
# c.expects(:render).raises(Exception)
|
103
104
|
begin
|
104
|
-
silence_logger {
|
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
|
-
|
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
|
-
|
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 {
|
130
|
+
silence_logger { @site.publish_all }
|
125
131
|
rescue Exception; end
|
126
|
-
|
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 {
|
136
|
+
silence_logger { @site.publish_pages([change1]) }
|
130
137
|
rescue Exception; end
|
131
|
-
|
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
|
-
|
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.
|
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
|
-
|
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
|
-
|
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
|
-
|
214
|
-
result =
|
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
|
-
|
217
|
-
result =
|
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
|
-
|
220
|
-
result =
|
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
|
-
|
223
|
-
result =
|
234
|
+
expected = "Page: '#{page.title}' 2\n"
|
235
|
+
result = @template_revision.static_template(output)
|
224
236
|
end
|
225
|
-
|
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
|
-
|
252
|
-
|
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
|
-
|
259
|
-
|
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
|
-
|
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
|
-
|
286
|
+
@site.after_publish do |revision|
|
274
287
|
publish1.finished(revision)
|
275
288
|
end
|
276
|
-
|
289
|
+
@site.after_publish do
|
277
290
|
publish2.finished
|
278
291
|
end
|
279
292
|
Content.delete_revision(@revision+1)
|
280
|
-
|
281
|
-
|
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
|
-
|
299
|
+
@site.pending_revision.must_be_nil
|
287
300
|
refute Content.revision_exists?(published_revision)
|
288
301
|
|
289
|
-
|
302
|
+
@site.after_publish do |revision|
|
290
303
|
raise "Boom"
|
291
304
|
end
|
292
305
|
|
293
306
|
begin
|
294
|
-
silence_logger {
|
307
|
+
silence_logger { @site.publish_all }
|
295
308
|
rescue Exception; end
|
296
309
|
|
297
|
-
|
298
|
-
|
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)
|
data/test/unit/test_render.rb
CHANGED
@@ -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
|
-
|
86
|
-
|
87
|
-
|
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=['
|
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.
|
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
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
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
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
@
|
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
|