spontaneous 0.2.0.beta5 → 0.2.0.beta6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +39 -0
- data/Gemfile +2 -0
- data/Readme.markdown +4 -4
- data/application/css/core.css.scss +144 -43
- data/application/css/definitions.css.scss +50 -16
- data/application/css/dialogue.css.scss +5 -2
- data/application/css/editing.css.scss +7 -7
- data/application/css/font.css.scss +1 -1
- data/application/css/meta.css.scss +6 -6
- data/application/css/popover.css.scss +6 -6
- data/application/css/top.css.scss +8 -1
- data/application/js/add_alias_dialogue.js +137 -36
- data/application/js/add_home_dialogue.js +10 -10
- data/application/js/ajax.js +26 -26
- data/application/js/authentication.js +2 -2
- data/application/js/box.js +21 -10
- data/application/js/box_container.js +13 -7
- data/application/js/compatibility.js +19 -17
- data/application/js/conflicted_field_dialogue.js +5 -5
- data/application/js/content.js +22 -16
- data/application/js/content_area.js +62 -33
- data/application/js/dialogue.js +16 -16
- data/application/js/dom.js +9 -10
- data/application/js/edit_panel.js +25 -20
- data/application/js/editing.js +21 -8
- data/application/js/entry.js +1 -1
- data/application/js/extensions.js +11 -11
- data/application/js/field/boolean.js +6 -6
- data/application/js/field/date.js +1 -1
- data/application/js/field/file.js +17 -17
- data/application/js/field/image.js +27 -27
- data/application/js/field/markdown.js +72 -71
- data/application/js/field/select.js +9 -9
- data/application/js/field/string.js +3 -3
- data/application/js/field/webvideo.js +2 -2
- data/application/js/field_preview.js +3 -0
- data/application/js/init.js +3 -2
- data/application/js/jquery-selection-position.js +13 -13
- data/application/js/location.js +17 -12
- data/application/js/login.js +2 -2
- data/application/js/meta_view/user_admin.js +101 -101
- data/application/js/metadata.js +1 -1
- data/application/js/page.js +2 -2
- data/application/js/page_browser.js +13 -13
- data/application/js/page_entry.js +1 -1
- data/application/js/panel/root_menu.js +10 -10
- data/application/js/popover.js +6 -5
- data/application/js/popover_view.js +5 -5
- data/application/js/preview.js +10 -4
- data/application/js/progress.js +6 -6
- data/application/js/properties.js +35 -6
- data/application/js/publish.js +43 -43
- data/application/js/require.js +14 -14
- data/application/js/services.js +3 -3
- data/application/js/sharded_upload.js +9 -8
- data/application/js/side_bar.js +5 -5
- data/application/js/state.js +2 -2
- data/application/js/status_bar.js +6 -6
- data/application/js/top_bar.js +97 -65
- data/application/js/types.js +9 -6
- data/application/js/upload.js +4 -4
- data/application/js/upload_manager.js +21 -21
- data/application/js/user.js +1 -1
- data/application/js/vendor/jquery.velocity.min.js +7 -0
- data/application/js/views.js +32 -8
- data/application/js/views/box_view.js +51 -31
- data/application/js/views/page_piece_view.js +17 -15
- data/application/js/views/page_view.js +54 -43
- data/application/js/views/piece_view.js +44 -37
- data/application/static/font/fontawesome-webfont-4f0022f25672c7f501c339cbf98d9117.ttf +0 -0
- data/application/views/index.erb +1 -0
- data/db/migrations/20130114120000_create_revision_tables.rb +2 -1
- data/db/migrations/20130813111009_increase_path_length.rb +11 -2
- data/db/migrations/20140506171823_add_index_to_target_id.rb +11 -0
- data/db/migrations/20140514090204_add_content_hash.rb +59 -0
- data/db/migrations/20140519150253_add_content_hash_timestamp.rb +20 -0
- data/lib/spontaneous.rb +0 -1
- data/lib/spontaneous/asset/environment.rb +77 -15
- data/lib/spontaneous/box.rb +21 -0
- data/lib/spontaneous/capistrano/deploy.rb +1 -1
- data/lib/spontaneous/capistrano/sync.rb +8 -7
- data/lib/spontaneous/change.rb +4 -2
- data/lib/spontaneous/cli/fields.rb +7 -3
- data/lib/spontaneous/cli/generate.rb +2 -0
- data/lib/spontaneous/cli/init.rb +24 -93
- data/lib/spontaneous/cli/init/db.rb +94 -0
- data/lib/spontaneous/cli/init/mysql.rb +17 -0
- data/lib/spontaneous/cli/init/postgresql.rb +33 -0
- data/lib/spontaneous/cli/init/sqlite.rb +14 -0
- data/lib/spontaneous/cli/site.rb +45 -20
- data/lib/spontaneous/collections/box_set.rb +3 -0
- data/lib/spontaneous/collections/entry_set.rb +43 -4
- data/lib/spontaneous/collections/field_set.rb +14 -2
- data/lib/spontaneous/data_mapper.rb +40 -7
- data/lib/spontaneous/data_mapper/content_model.rb +1 -1
- data/lib/spontaneous/data_mapper/content_model/associations.rb +63 -12
- data/lib/spontaneous/data_mapper/content_model/timestamps.rb +9 -14
- data/lib/spontaneous/data_mapper/content_table.rb +4 -2
- data/lib/spontaneous/data_mapper/dataset.rb +31 -2
- data/lib/spontaneous/data_mapper/scope.rb +37 -20
- data/lib/spontaneous/errors.rb +6 -0
- data/lib/spontaneous/facet.rb +20 -10
- data/lib/spontaneous/field/base.rb +8 -1
- data/lib/spontaneous/field/file.rb +28 -3
- data/lib/spontaneous/field/image.rb +2 -0
- data/lib/spontaneous/field/update.rb +6 -0
- data/lib/spontaneous/field/webvideo/vimeo.rb +6 -1
- data/lib/spontaneous/field/webvideo/vine.rb +1 -1
- data/lib/spontaneous/field/webvideo/youtube.rb +1 -1
- data/lib/spontaneous/generators/site.rb +6 -4
- data/lib/spontaneous/generators/site/.gitignore +1 -0
- data/lib/spontaneous/generators/site/Gemfile.tt +3 -3
- data/lib/spontaneous/generators/site/config/{indexes.rb.tt → initializers/indexes.rb.tt} +0 -0
- data/lib/spontaneous/generators/site/config/initializers/publishing.rb.tt +78 -0
- data/lib/spontaneous/generators/site/{config/database.yml.tt → db/mysql2.yml.tt} +7 -6
- data/lib/spontaneous/generators/site/db/postgres.yml.tt +25 -0
- data/lib/spontaneous/generators/site/db/sqlite3.yml.tt +18 -0
- data/lib/spontaneous/generators/site/public/humans.txt.tt +14 -0
- data/lib/spontaneous/generators/site/templates/layouts/standard.html.cut.tt +51 -0
- data/lib/spontaneous/loader.rb +1 -1
- data/lib/spontaneous/logger.rb +1 -1
- data/lib/spontaneous/media/image/optimizer.rb +1 -1
- data/lib/spontaneous/media/image/processor.rb +11 -2
- data/lib/spontaneous/media/image/renderable.rb +2 -0
- data/lib/spontaneous/model.rb +3 -0
- data/lib/spontaneous/model/box/allowed_types.rb +17 -4
- data/lib/spontaneous/model/core.rb +36 -3
- data/lib/spontaneous/model/core/aliases.rb +5 -2
- data/lib/spontaneous/model/core/boxes.rb +6 -0
- data/lib/spontaneous/model/core/cascading_change.rb +38 -0
- data/lib/spontaneous/model/core/content_hash.rb +171 -0
- data/lib/spontaneous/model/core/entries.rb +0 -19
- data/lib/spontaneous/model/core/fields.rb +11 -0
- data/lib/spontaneous/model/core/modifications.rb +22 -21
- data/lib/spontaneous/model/core/render.rb +3 -0
- data/lib/spontaneous/model/core/serialisation.rb +18 -17
- data/lib/spontaneous/model/page.rb +35 -8
- data/lib/spontaneous/model/page/page_tree.rb +20 -8
- data/lib/spontaneous/model/page/paths.rb +79 -50
- data/lib/spontaneous/model/page/singleton.rb +71 -0
- data/lib/spontaneous/model/page/site_map.rb +2 -1
- data/lib/spontaneous/model/page/site_timestamps.rb +2 -2
- data/lib/spontaneous/model/piece.rb +10 -0
- data/lib/spontaneous/output/context.rb +13 -6
- data/lib/spontaneous/output/format.rb +30 -5
- data/lib/spontaneous/output/helpers/script_helper.rb +8 -0
- data/lib/spontaneous/output/helpers/stylesheet_helper.rb +7 -0
- data/lib/spontaneous/output/renderable.rb +16 -0
- data/lib/spontaneous/output/store.rb +1 -1
- data/lib/spontaneous/output/template/renderer.rb +2 -2
- data/lib/spontaneous/page_piece.rb +25 -1
- data/lib/spontaneous/prototypes/box_prototype.rb +13 -0
- data/lib/spontaneous/prototypes/field_prototype.rb +7 -4
- data/lib/spontaneous/publishing.rb +10 -5
- data/lib/spontaneous/publishing/immediate.rb +32 -349
- data/lib/spontaneous/publishing/pipeline.rb +43 -0
- data/lib/spontaneous/publishing/progress.rb +186 -0
- data/lib/spontaneous/publishing/publish.rb +107 -0
- data/lib/spontaneous/publishing/rerender.rb +17 -0
- data/lib/spontaneous/publishing/revision.rb +53 -18
- data/lib/spontaneous/publishing/simultaneous.rb +1 -1
- data/lib/spontaneous/publishing/steps.rb +154 -0
- data/lib/spontaneous/publishing/steps/activate_revision.rb +45 -0
- data/lib/spontaneous/publishing/steps/archive_old_revisions.rb +22 -0
- data/lib/spontaneous/publishing/steps/base_step.rb +49 -0
- data/lib/spontaneous/publishing/steps/copy_static_files.rb +74 -0
- data/lib/spontaneous/publishing/steps/create_revision_directory.rb +24 -0
- data/lib/spontaneous/publishing/steps/generate_rackup_file.rb +51 -0
- data/lib/spontaneous/publishing/steps/generate_search_indexes.rb +24 -0
- data/lib/spontaneous/publishing/steps/render_revision.rb +69 -0
- data/lib/spontaneous/publishing/steps/write_revision_file.rb +43 -0
- data/lib/spontaneous/rack/back.rb +3 -1
- data/lib/spontaneous/rack/back/alias.rb +9 -8
- data/lib/spontaneous/rack/front.rb +1 -1
- data/lib/spontaneous/rack/middleware.rb +7 -4
- data/lib/spontaneous/rack/middleware/transaction.rb +14 -0
- data/lib/spontaneous/rack/page_controller.rb +23 -8
- data/lib/spontaneous/revision.rb +5 -10
- data/lib/spontaneous/schema.rb +5 -0
- data/lib/spontaneous/server.rb +3 -1
- data/lib/spontaneous/site.rb +17 -10
- data/lib/spontaneous/site/publishing.rb +25 -3
- data/lib/spontaneous/site/state.rb +7 -3
- data/lib/spontaneous/tasks/database.rake +5 -10
- data/lib/spontaneous/utils/database/mysql_dumper.rb +5 -1
- data/lib/spontaneous/version.rb +1 -1
- data/spontaneous.gemspec +4 -3
- data/test/fixtures/example_application/config/initializers/initializer1.rb +1 -0
- data/test/fixtures/example_application/config/initializers/initializer2.rb +1 -0
- data/test/fixtures/example_application/config/initializers/publishing.rb +13 -0
- data/test/fixtures/search/config/{indexes.rb → initializers/indexes.rb} +0 -0
- data/test/fixtures/serialisation/root_hash.yaml.erb +10 -4
- data/test/functional/test_application.rb +10 -0
- data/test/functional/test_back.rb +23 -5
- data/test/functional/test_cli.rb +98 -34
- data/test/functional/test_front.rb +7 -3
- data/test/test_helper.rb +35 -28
- data/test/unit/test_alias.rb +20 -3
- data/test/unit/test_assets.rb +58 -30
- data/test/unit/test_changesets.rb +20 -12
- data/test/unit/test_content_hash.rb +496 -0
- data/test/unit/test_context.rb +28 -1
- data/test/unit/test_controllers.rb +96 -61
- data/test/unit/test_crypt.rb +1 -8
- data/test/unit/test_datamapper.rb +95 -19
- data/test/unit/test_features.rb +1 -4
- data/test/unit/test_fields.rb +61 -12
- data/test/unit/test_generators.rb +39 -2
- data/test/unit/test_images.rb +3 -1
- data/test/unit/test_modifications.rb +224 -219
- data/test/unit/test_output_store.rb +10 -0
- data/test/unit/{test_formats.rb → test_outputs.rb} +75 -6
- data/test/unit/test_page.rb +61 -15
- data/test/unit/test_plugins.rb +2 -42
- data/test/unit/test_publishing_pipeline.rb +1050 -0
- data/test/unit/test_render.rb +30 -0
- data/test/unit/test_revisions.rb +110 -2
- data/test/unit/test_schema.rb +4 -0
- data/test/unit/test_search.rb +1 -1
- data/test/unit/test_serialisation.rb +6 -1
- data/test/unit/test_singletons.rb +159 -0
- data/test/unit/test_site.rb +71 -44
- metadata +140 -86
- data/application/static/font/fontawesome-webfont-1c66a4738b40ef0f6b1abca0ba9a796d.ttf +0 -0
- data/test/unit/test_publishing.rb +0 -330
@@ -44,10 +44,12 @@ describe "Front" do
|
|
44
44
|
end
|
45
45
|
|
46
46
|
class ::DynamicRequestParams < ::Page
|
47
|
+
singleton
|
47
48
|
layout(:html) { "{{ params[:horse] }}*{{ equine }}" }
|
48
49
|
end
|
49
50
|
|
50
51
|
class ::DynamicRenderParams < ::Page
|
52
|
+
singleton
|
51
53
|
add_output :mobile
|
52
54
|
add_output :session
|
53
55
|
add_output :params
|
@@ -101,6 +103,8 @@ describe "Front" do
|
|
101
103
|
|
102
104
|
Content.delete_revision(1) rescue nil
|
103
105
|
|
106
|
+
site.publish_steps = Spontaneous::Publishing::Steps.default
|
107
|
+
|
104
108
|
Spontaneous.logger.silent! {
|
105
109
|
site.publish_all
|
106
110
|
}
|
@@ -271,7 +275,7 @@ describe "Front" do
|
|
271
275
|
get { render "caterpillars" }
|
272
276
|
end
|
273
277
|
get '/dynamic-render-params'
|
274
|
-
assert last_response.status == 404
|
278
|
+
assert last_response.status == 404, "Expected 404 but got #{last_response.status}"
|
275
279
|
end
|
276
280
|
|
277
281
|
it "return the right status code" do
|
@@ -325,7 +329,7 @@ describe "Front" do
|
|
325
329
|
|
326
330
|
it "allows setting status code and passing parameters to the show call" do
|
327
331
|
DynamicRenderParams.controller do
|
328
|
-
get { render
|
332
|
+
get { render DynamicRenderParams, 401, :teeth => "white" }
|
329
333
|
end
|
330
334
|
get '/dynamic-render-params'
|
331
335
|
assert last_response.status == 401
|
@@ -334,7 +338,7 @@ describe "Front" do
|
|
334
338
|
|
335
339
|
it "allows passing parameters to the render call" do
|
336
340
|
DynamicRenderParams.controller do
|
337
|
-
get { render
|
341
|
+
get { render DynamicRenderParams, :teeth => "white" }
|
338
342
|
end
|
339
343
|
get '/dynamic-render-params'
|
340
344
|
assert last_response.status == 200
|
data/test/test_helper.rb
CHANGED
@@ -17,6 +17,7 @@ $:.unshift(test_path) if File.directory?(test_path) && !$:.include?(test_path)
|
|
17
17
|
$:.unshift(spot_path) if File.directory?(spot_path) && !$:.include?(spot_path)
|
18
18
|
|
19
19
|
require 'rack'
|
20
|
+
require 'timecop'
|
20
21
|
require 'logger'
|
21
22
|
|
22
23
|
Sequel.extension :migration
|
@@ -25,38 +26,46 @@ Sequel.extension :migration
|
|
25
26
|
# The scissors plugin adds class methods for update, delete, and destroy
|
26
27
|
Sequel::Model.plugin :scissors
|
27
28
|
|
28
|
-
|
29
|
-
ENV["SPOT_ADAPTER"] ||= "postgres"
|
29
|
+
ENV["SPOT_ADAPTER"] ||= "sqlite"
|
30
30
|
|
31
31
|
jruby = case RUBY_PLATFORM
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
32
|
+
when "java"
|
33
|
+
true
|
34
|
+
else
|
35
|
+
false
|
36
|
+
end
|
37
37
|
|
38
38
|
|
39
39
|
connection_string = \
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
40
|
+
case ENV["SPOT_ADAPTER"]
|
41
|
+
when "postgres"
|
42
|
+
if jruby
|
43
|
+
require 'jdbc/postgres'
|
44
|
+
Jdbc::Postgres.load_driver
|
45
|
+
"jdbc:postgresql:///spontaneous2_test"
|
46
|
+
else
|
47
|
+
require 'pg'
|
48
|
+
"postgres:///spontaneous2_test"
|
49
|
+
end
|
50
|
+
when "mysql"
|
51
|
+
if jruby
|
52
|
+
require 'jdbc/mysql'
|
53
|
+
Jdbc::MySQL.load_driver
|
54
|
+
"jdbc:mysql://localhost/spontaneous2_test?user=root"
|
55
|
+
else
|
56
|
+
require 'mysql2'
|
57
|
+
"mysql2://root@localhost/spontaneous2_test"
|
58
|
+
end
|
59
|
+
when "sqlite"
|
60
|
+
if jruby
|
61
|
+
require 'jdbc/sqlite3'
|
62
|
+
Jdbc::SQLite3.load_driver
|
63
|
+
"jdbc:sqlite::memory:"
|
64
|
+
else
|
65
|
+
require 'sqlite3'
|
66
|
+
"sqlite:/" # in-memory
|
59
67
|
end
|
68
|
+
end
|
60
69
|
|
61
70
|
puts "SPOT_ADAPTER=#{ENV["SPOT_ADAPTER"]} => #{connection_string}"
|
62
71
|
|
@@ -240,5 +249,3 @@ class MiniTest::Spec
|
|
240
249
|
end
|
241
250
|
|
242
251
|
require 'minitest/autorun'
|
243
|
-
|
244
|
-
|
data/test/unit/test_alias.rb
CHANGED
@@ -321,9 +321,6 @@ describe "Alias" do
|
|
321
321
|
end
|
322
322
|
|
323
323
|
|
324
|
-
# TODO
|
325
|
-
it "reference the aliases fields before the targets"
|
326
|
-
|
327
324
|
it "present their target's fields as their own" do
|
328
325
|
assert @a_alias.field?(:a_field1)
|
329
326
|
@a_alias.a_field1.value.must_equal a.a_field1.value
|
@@ -333,6 +330,14 @@ describe "Alias" do
|
|
333
330
|
@a_alias.target.a_field1.value.must_equal a.a_field1.value
|
334
331
|
end
|
335
332
|
|
333
|
+
it "provide transparent access target's fields" do
|
334
|
+
@a_alias.a_field1.value.must_equal a.a_field1.value
|
335
|
+
end
|
336
|
+
|
337
|
+
it "provide transparent access target's fields with hash notation" do
|
338
|
+
@a_alias.fields[:a_field1].value.must_equal a.a_field1.value
|
339
|
+
end
|
340
|
+
|
336
341
|
it "have their own styles" do
|
337
342
|
assert_correct_template(@a_alias, template_root / 'a_alias/a_alias_style', renderer)
|
338
343
|
end
|
@@ -477,6 +482,18 @@ describe "Alias" do
|
|
477
482
|
bl.path.must_equal "/aliases/newb/newb"
|
478
483
|
end
|
479
484
|
|
485
|
+
it "include target values in serialisation" do
|
486
|
+
al = BAlias.create(:target => b)
|
487
|
+
al.export[:target].must_equal b.shallow_export(nil)
|
488
|
+
end
|
489
|
+
|
490
|
+
it "include target values in entry serialisation" do
|
491
|
+
al = BAlias.create(:target => b)
|
492
|
+
aliases.box1 << al
|
493
|
+
aliases.save
|
494
|
+
al.entry.export[:target].must_equal b.shallow_export(nil)
|
495
|
+
end
|
496
|
+
|
480
497
|
it "update their path if their parent's path changes" do
|
481
498
|
al = BAlias.create(:target => b, :slug => "balias")
|
482
499
|
bl = BAlias.create(:target => b, :slug => "balias")
|
data/test/unit/test_assets.rb
CHANGED
@@ -93,6 +93,8 @@ describe "Assets" do
|
|
93
93
|
end
|
94
94
|
|
95
95
|
after do
|
96
|
+
tmp = site.path('assets/tmp')
|
97
|
+
FileUtils.rm_r(tmp) if tmp.exist?
|
96
98
|
Content.delete
|
97
99
|
end
|
98
100
|
|
@@ -221,7 +223,7 @@ describe "Assets" do
|
|
221
223
|
result = last_response.body
|
222
224
|
result.must_match /var a = 1/
|
223
225
|
result.must_match /var b = 2/
|
224
|
-
result.must_match
|
226
|
+
result.must_match %r{alert\("I knew it!"\);}
|
225
227
|
end
|
226
228
|
|
227
229
|
it "should preprocess coffeescript" do
|
@@ -235,7 +237,7 @@ describe "Assets" do
|
|
235
237
|
get "/assets/x.js"
|
236
238
|
assert last_response.ok?, "Recieved #{last_response.status} not 200"
|
237
239
|
result = last_response.body
|
238
|
-
result.must_match
|
240
|
+
result.must_match %r{var x = 1;}
|
239
241
|
end
|
240
242
|
|
241
243
|
it "should use absolute URLs when encountered" do
|
@@ -273,15 +275,15 @@ describe "Assets" do
|
|
273
275
|
get "/assets/css/all.css"
|
274
276
|
assert last_response.ok?, "Recieved #{last_response.status} not 200"
|
275
277
|
result = last_response.body
|
276
|
-
result.must_match
|
277
|
-
result.must_match
|
278
|
+
result.must_match %r{height: 42px;}
|
279
|
+
result.must_match %r{width: 8px;}
|
278
280
|
end
|
279
281
|
|
280
282
|
it "should compile sass" do
|
281
283
|
get "/assets/css/b.css"
|
282
284
|
assert last_response.ok?, "Recieved #{last_response.status} not 200"
|
283
285
|
result = last_response.body
|
284
|
-
result.must_match
|
286
|
+
result.must_match %r{height: 42px;}
|
285
287
|
end
|
286
288
|
|
287
289
|
it "links to images" do
|
@@ -295,7 +297,7 @@ describe "Assets" do
|
|
295
297
|
get "/assets/css/missing.css"
|
296
298
|
assert last_response.ok?, "Recieved #{last_response.status} not 200"
|
297
299
|
result = last_response.body
|
298
|
-
result.must_match
|
300
|
+
result.must_match %r{background: url\(i\/missing\.png\)}
|
299
301
|
end
|
300
302
|
|
301
303
|
it "can understand urls with hashes" do
|
@@ -337,7 +339,7 @@ describe "Assets" do
|
|
337
339
|
describe "publishing" do
|
338
340
|
let(:app) { Spontaneous::Rack::Front.application(site) }
|
339
341
|
let(:context) { live_context }
|
340
|
-
let(:revision) {
|
342
|
+
let(:revision) { site.revision(context.revision) }
|
341
343
|
|
342
344
|
before do
|
343
345
|
FileUtils.rm_f(Spontaneous.revision_dir) if File.exist?(Spontaneous.revision_dir)
|
@@ -350,25 +352,27 @@ describe "Assets" do
|
|
350
352
|
end
|
351
353
|
|
352
354
|
describe "javascript" do
|
355
|
+
let(:all_sha) { "b1d3d85feff4d68e16d2b4da97717aa0" }
|
356
|
+
let(:x_sha) { "cf638f60cff3ce84f156cb4621a914b4" }
|
353
357
|
it "bundles & fingerprints local scripts" do
|
354
358
|
result = context.scripts('js/all', 'js/m.js', 'js/c.js', 'x')
|
355
359
|
result.must_equal [
|
356
|
-
|
357
|
-
'<script type="text/javascript" src="/assets/js/m-
|
358
|
-
'<script type="text/javascript" src="/assets/js/c-
|
359
|
-
|
360
|
+
%(<script type="text/javascript" src="/assets/js/all-#{all_sha}.js"></script>),
|
361
|
+
'<script type="text/javascript" src="/assets/js/m-424bd92768589875beac31e333399631.js"></script>',
|
362
|
+
'<script type="text/javascript" src="/assets/js/c-ac0d40982cc84fc656234ef2a57e09e8.js"></script>',
|
363
|
+
%(<script type="text/javascript" src="/assets/x-#{x_sha}.js"></script>)
|
360
364
|
].join("\n")
|
361
365
|
end
|
362
366
|
|
363
367
|
it "writes bundled assets to the revision directory" do
|
364
368
|
result = context.scripts('js/all')
|
365
|
-
asset_path = revision.path("assets/js/all
|
369
|
+
asset_path = revision.path("assets/js/all-#{all_sha}.js")
|
366
370
|
assert asset_path.exist?
|
367
371
|
end
|
368
372
|
|
369
373
|
it "compresses local scripts" do
|
370
374
|
result = context.scripts('js/all')
|
371
|
-
asset_path = revision.path("assets/js/all
|
375
|
+
asset_path = revision.path("assets/js/all-#{all_sha}.js")
|
372
376
|
js = asset_path.read
|
373
377
|
js.index("\n").must_be_nil
|
374
378
|
end
|
@@ -376,23 +380,23 @@ describe "Assets" do
|
|
376
380
|
it "bundles locals scripts and includes remote ones" do
|
377
381
|
result = context.scripts('js/all', '//use.typekit.com/abcde', 'http://cdn.google.com/jquery.js', 'x')
|
378
382
|
result.must_equal [
|
379
|
-
|
383
|
+
%(<script type="text/javascript" src="/assets/js/all-#{all_sha}.js"></script>),
|
380
384
|
'<script type="text/javascript" src="//use.typekit.com/abcde"></script>',
|
381
385
|
'<script type="text/javascript" src="http://cdn.google.com/jquery.js"></script>',
|
382
|
-
|
386
|
+
%(<script type="text/javascript" src="/assets/x-#{x_sha}.js"></script>)
|
383
387
|
].join("\n")
|
384
388
|
end
|
385
389
|
|
386
390
|
it "makes bundled scripts available under /assets" do
|
387
391
|
context.scripts('js/all')
|
388
|
-
get "/assets/js/all
|
389
|
-
asset_path = revision.path("assets/js/all
|
392
|
+
get "/assets/js/all-#{all_sha}.js"
|
393
|
+
asset_path = revision.path("assets/js/all-#{all_sha}.js")
|
390
394
|
last_response.body.must_equal asset_path.read
|
391
395
|
end
|
392
396
|
|
393
397
|
it "only bundles & compresses once" do
|
394
398
|
context.scripts('js/all')
|
395
|
-
asset_path = revision.path("assets/js/all
|
399
|
+
asset_path = revision.path("assets/js/all-#{all_sha}.js")
|
396
400
|
assert asset_path.exist?
|
397
401
|
asset_path.open("w") do |file|
|
398
402
|
file.write("var cached = true;")
|
@@ -400,22 +404,44 @@ describe "Assets" do
|
|
400
404
|
context.scripts('js/all')
|
401
405
|
asset_path.read.must_equal "var cached = true;"
|
402
406
|
end
|
407
|
+
describe "re-use" do
|
408
|
+
before do
|
409
|
+
@result = context.scripts('js/all', 'x')
|
410
|
+
end
|
411
|
+
|
412
|
+
it "uses assets from a previous publish if present" do
|
413
|
+
context = live_context
|
414
|
+
def context.revision; 100 end
|
415
|
+
revision = site.revision(context.revision)
|
416
|
+
manifest = Spontaneous::JSON.parse File.read(site.path("assets/tmp") + "manifest.json")
|
417
|
+
compiled = manifest[:assets][:"js/all.js"]
|
418
|
+
::File.open(site.path("assets/tmp")+compiled, 'w') do |file|
|
419
|
+
file.write("var reused = true;")
|
420
|
+
end
|
421
|
+
result = context.scripts('js/all', 'x')
|
422
|
+
rev = revision.path("assets") + compiled
|
423
|
+
File.read(rev).must_equal "var reused = true;"
|
424
|
+
end
|
425
|
+
end
|
403
426
|
end
|
404
427
|
|
405
428
|
describe "css" do
|
429
|
+
let(:all_sha) { "2468ffc5102b6bfcaf69a4fc8db59fdd" }
|
430
|
+
let(:x_sha) { "ae3ee1dc79a34d24e28456118c1b9623" }
|
431
|
+
|
406
432
|
it "bundles & fingerprints local stylesheets" do
|
407
433
|
result = context.stylesheets('css/all', 'css/a.css', 'x')
|
408
434
|
result.must_equal [
|
409
|
-
|
410
|
-
'<link rel="stylesheet" href="/assets/css/a-
|
411
|
-
|
435
|
+
%(<link rel="stylesheet" href="/assets/css/all-#{all_sha}.css" />),
|
436
|
+
'<link rel="stylesheet" href="/assets/css/a-35b26d0cd9c7ebff494c8627e0d4ed14.css" />',
|
437
|
+
%(<link rel="stylesheet" href="/assets/x-#{x_sha}.css" />)
|
412
438
|
].join("\n")
|
413
439
|
end
|
414
440
|
|
415
441
|
it "ignores missing stylesheets" do
|
416
442
|
result = context.stylesheets('css/all', '/css/notfound', 'css/notfound')
|
417
443
|
result.must_equal [
|
418
|
-
|
444
|
+
%(<link rel="stylesheet" href="/assets/css/all-#{all_sha}.css" />),
|
419
445
|
'<link rel="stylesheet" href="/css/notfound" />',
|
420
446
|
'<link rel="stylesheet" href="css/notfound" />'
|
421
447
|
].join("\n")
|
@@ -424,10 +450,10 @@ describe "Assets" do
|
|
424
450
|
it "bundles locals scripts and includes remote ones" do
|
425
451
|
result = context.stylesheets('css/all.css', '//stylesheet.com/responsive', 'http://cdn.google.com/normalize.css', 'x')
|
426
452
|
result.must_equal [
|
427
|
-
|
453
|
+
%(<link rel="stylesheet" href="/assets/css/all-#{all_sha}.css" />),
|
428
454
|
'<link rel="stylesheet" href="//stylesheet.com/responsive" />',
|
429
455
|
'<link rel="stylesheet" href="http://cdn.google.com/normalize.css" />',
|
430
|
-
|
456
|
+
%(<link rel="stylesheet" href="/assets/x-#{x_sha}.css" />)
|
431
457
|
].join("\n")
|
432
458
|
end
|
433
459
|
|
@@ -473,15 +499,17 @@ describe "Assets" do
|
|
473
499
|
end
|
474
500
|
end
|
475
501
|
|
502
|
+
let(:y_sha) { "e2b6a69468b467c7414ae0e12124a66e" }
|
503
|
+
|
476
504
|
describe "images" do
|
477
505
|
it "bundles images and links using fingerprinted asset url" do
|
478
506
|
path = context.stylesheet_urls('css/image1').first
|
479
507
|
get path
|
480
508
|
assert last_response.ok?, "Recieved #{last_response.status} not 200"
|
481
509
|
result = last_response.body
|
482
|
-
result.must_match %r{background:url\(/assets/i/y
|
510
|
+
result.must_match %r{background:url\(/assets/i/y-#{y_sha}\.png\)}
|
483
511
|
|
484
|
-
asset_path = revision.path("/assets/i/y
|
512
|
+
asset_path = revision.path("/assets/i/y-#{y_sha}.png")
|
485
513
|
assert asset_path.exist?
|
486
514
|
end
|
487
515
|
|
@@ -498,8 +526,8 @@ describe "Assets" do
|
|
498
526
|
get path
|
499
527
|
assert last_response.ok?, "Recieved #{last_response.status} not 200"
|
500
528
|
result = last_response.body
|
501
|
-
result.must_match %r{background:url\(/assets/i/y
|
502
|
-
asset_path = revision.path("/assets/i/y
|
529
|
+
result.must_match %r{background:url\(/assets/i/y-#{y_sha}\.png\?query=true#hash\)}
|
530
|
+
asset_path = revision.path("/assets/i/y-#{y_sha}.png")
|
503
531
|
assert asset_path.exist?
|
504
532
|
end
|
505
533
|
end
|
@@ -509,11 +537,11 @@ describe "Assets" do
|
|
509
537
|
|
510
538
|
it "should allow for embedding asset images into templates" do
|
511
539
|
result = renderer.render_string("${ asset_path 'i/y.png' }", @page.output(:html))
|
512
|
-
result.must_equal "/assets/i/y
|
540
|
+
result.must_equal "/assets/i/y-#{y_sha}.png"
|
513
541
|
end
|
514
542
|
it "should allow for embedding asset urls into templates" do
|
515
543
|
result = renderer.render_string("${ asset_url 'i/y.png' }", @page.output(:html))
|
516
|
-
result.must_equal "url(/assets/i/y
|
544
|
+
result.must_equal "url(/assets/i/y-#{y_sha}.png)"
|
517
545
|
end
|
518
546
|
end
|
519
547
|
end
|
@@ -9,10 +9,11 @@ describe "Change" do
|
|
9
9
|
@now = Time.now
|
10
10
|
@site = setup_site
|
11
11
|
|
12
|
-
|
12
|
+
Timecop.freeze(@now)
|
13
13
|
@revision = 1
|
14
14
|
|
15
15
|
Content.delete
|
16
|
+
Spontaneous::State.delete
|
16
17
|
|
17
18
|
class ::Page
|
18
19
|
field :title, :string, :default => "New Page"
|
@@ -25,6 +26,7 @@ describe "Change" do
|
|
25
26
|
end
|
26
27
|
|
27
28
|
after do
|
29
|
+
Timecop.return
|
28
30
|
Content.delete_revision(@revision) rescue nil
|
29
31
|
Content.delete_revision(@revision+1) rescue nil
|
30
32
|
Content.delete
|
@@ -55,8 +57,9 @@ describe "Change" do
|
|
55
57
|
|
56
58
|
it "list all newly created pages" do
|
57
59
|
root = Page.create(:title => "root")
|
58
|
-
root[:first_published_at] = root[:last_published_at] = root.modified_at + 1000
|
59
60
|
root.save
|
61
|
+
Content.publish(@revision)
|
62
|
+
|
60
63
|
|
61
64
|
5.times { |i| root.things << Page.create(:title => "Page #{i+1}") }
|
62
65
|
|
@@ -75,9 +78,6 @@ describe "Change" do
|
|
75
78
|
it "not list new pieces as available for publish" do
|
76
79
|
root = Page.create(:title => "root")
|
77
80
|
Content.publish(@revision)
|
78
|
-
# force root to appear in the modified lists -- need this because otherwise the changes happen
|
79
|
-
# more quickly than the resolution of the timestamps can register
|
80
|
-
root[:first_published_at] = root[:last_published_at] = root.modified_at - 1000
|
81
81
|
root.things << Piece.new
|
82
82
|
root.save.reload
|
83
83
|
result = outstanding_changes[:changes]
|
@@ -219,11 +219,14 @@ describe "Change" do
|
|
219
219
|
root.reload
|
220
220
|
page1 = Page.new(:title => "Page 1")
|
221
221
|
root.things << page1
|
222
|
+
root.save.reload
|
223
|
+
page1.save.reload
|
224
|
+
last = Time.now + 100
|
225
|
+
Timecop.travel(last)
|
222
226
|
new_child1 = Page.new(:title => "New Child 1")
|
223
227
|
page1.things << new_child1
|
224
|
-
|
225
|
-
|
226
|
-
::Content.filter(:id => new_child1.id).update(:modified_at => last)
|
228
|
+
page1.save
|
229
|
+
new_child1.save
|
227
230
|
result = outstanding_changes[:changes]
|
228
231
|
assert result.first.modified_at > result.last.modified_at, "Change list in incorrect order"
|
229
232
|
end
|
@@ -238,18 +241,21 @@ describe "Change" do
|
|
238
241
|
new_child1 = Page.new(:title => "New Child 1")
|
239
242
|
page1.things << new_child1
|
240
243
|
root.save
|
244
|
+
new_child1.save
|
241
245
|
|
242
246
|
Content.publish(@revision)
|
247
|
+
page1.reload
|
243
248
|
|
244
249
|
later = @now + 10
|
245
|
-
|
250
|
+
Timecop.travel(later)
|
246
251
|
old_slug = page1.slug
|
247
252
|
page1.slug = "changed"
|
248
|
-
page1.save
|
253
|
+
page1.save.reload
|
249
254
|
|
250
255
|
result = outstanding_changes[:changes]
|
251
256
|
|
252
257
|
change = result.detect { |change| change.page.id == page1.id }
|
258
|
+
refute change.nil?
|
253
259
|
change.export[:side_effects].must_equal({
|
254
260
|
:slug => [{ :count => 1, :created_at => later.httpdate, :old_value => old_slug, :new_value => "changed"}]
|
255
261
|
})
|
@@ -267,14 +273,16 @@ describe "Change" do
|
|
267
273
|
root.save
|
268
274
|
|
269
275
|
Content.publish(@revision)
|
276
|
+
page1.reload
|
270
277
|
|
271
278
|
later = @now + 10
|
272
|
-
|
279
|
+
Timecop.travel(later)
|
273
280
|
page1.hide!
|
274
281
|
|
275
|
-
|
282
|
+
|
276
283
|
result = outstanding_changes[:changes]
|
277
284
|
change = result.detect { |change| change.page.id == page1.id }
|
285
|
+
refute change.nil?
|
278
286
|
change.export[:side_effects].must_equal({
|
279
287
|
:visibility => [{ :count => 1, :created_at => later.httpdate, :old_value => false, :new_value => true}]
|
280
288
|
})
|