zen 0.4.2 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (131) hide show
  1. data/.gems +17 -15
  2. data/.gitignore +1 -1
  3. data/.travis.yml +1 -1
  4. data/MANIFEST +470 -0
  5. data/README.md +5 -3
  6. data/Rakefile +8 -6
  7. data/bin/zen +2 -7
  8. data/guide/asset_management.md +1 -0
  9. data/guide/autosaving_forms.md +1 -0
  10. data/guide/changelog.md +22 -0
  11. data/guide/faq.md +1 -0
  12. data/guide/getting_started.md +1 -0
  13. data/guide/hacking.md +1 -0
  14. data/guide/images/sections/revisions.png +0 -0
  15. data/guide/images/sections/revisions_diff.png +0 -0
  16. data/guide/images/sections/revisions_diff_multiple.png +0 -0
  17. data/guide/installation.md +4 -3
  18. data/guide/javascript.md +1 -0
  19. data/guide/javascript/zen_autosave.md +1 -0
  20. data/guide/javascript/zen_editor.md +1 -0
  21. data/guide/javascript/zen_form.md +1 -0
  22. data/guide/javascript/zen_hash.md +1 -0
  23. data/guide/javascript/zen_htmltable.md +1 -0
  24. data/guide/javascript/zen_tabs.md +1 -0
  25. data/guide/javascript/zen_window.md +1 -0
  26. data/guide/zen_compared.md +1 -0
  27. data/lib/zen.rb +10 -12
  28. data/lib/zen/event.rb +2 -2
  29. data/lib/zen/helper/controller.rb +13 -13
  30. data/lib/zen/helper/message.rb +3 -3
  31. data/lib/zen/helper/search.rb +4 -4
  32. data/lib/zen/helper/stacked_aspect.rb +9 -9
  33. data/lib/zen/html_diff.rb +151 -0
  34. data/lib/zen/language.rb +9 -7
  35. data/lib/zen/language/translation.rb +8 -8
  36. data/lib/zen/markup.rb +1 -1
  37. data/lib/zen/migrator.rb +2 -2
  38. data/lib/zen/model/helper.rb +4 -4
  39. data/lib/zen/model/plugin/events.rb +16 -16
  40. data/lib/zen/package.rb +2 -2
  41. data/lib/zen/package/all.rb +1 -1
  42. data/lib/zen/package/categories/lib/categories/controller/categories.rb +4 -4
  43. data/lib/zen/package/categories/lib/categories/controller/category_groups.rb +4 -4
  44. data/lib/zen/package/categories/lib/categories/helper/category.rb +3 -3
  45. data/lib/zen/package/categories/lib/categories/model/category.rb +9 -9
  46. data/lib/zen/package/categories/lib/categories/model/category_group.rb +9 -9
  47. data/lib/zen/package/comments/lib/comments/controller/comments.rb +4 -4
  48. data/lib/zen/package/comments/lib/comments/controller/comments_form.rb +2 -2
  49. data/lib/zen/package/comments/lib/comments/helper/comment.rb +1 -1
  50. data/lib/zen/package/comments/lib/comments/model/comment.rb +13 -13
  51. data/lib/zen/package/custom_fields/lib/custom_fields/blue_form_parameters.rb +1 -1
  52. data/lib/zen/package/custom_fields/lib/custom_fields/controller/custom_field_groups.rb +4 -4
  53. data/lib/zen/package/custom_fields/lib/custom_fields/controller/custom_field_types.rb +6 -6
  54. data/lib/zen/package/custom_fields/lib/custom_fields/controller/custom_fields.rb +5 -5
  55. data/lib/zen/package/custom_fields/lib/custom_fields/helper/custom_field.rb +3 -3
  56. data/lib/zen/package/custom_fields/lib/custom_fields/model/custom_field.rb +9 -9
  57. data/lib/zen/package/custom_fields/lib/custom_fields/model/custom_field_group.rb +9 -9
  58. data/lib/zen/package/custom_fields/lib/custom_fields/model/custom_field_type.rb +9 -9
  59. data/lib/zen/package/custom_fields/lib/custom_fields/model/custom_field_value.rb +8 -3
  60. data/lib/zen/package/custom_fields/migrations/1336171490_revisions.rb +41 -0
  61. data/lib/zen/package/dashboard/lib/dashboard/controller/dashboard.rb +6 -6
  62. data/lib/zen/package/dashboard/lib/dashboard/model/widget.rb +3 -3
  63. data/lib/zen/package/dashboard/lib/dashboard/widget.rb +12 -12
  64. data/lib/zen/package/extensions/lib/extensions/controller/extensions.rb +3 -3
  65. data/lib/zen/package/menus/lib/menus/controller/menu_items.rb +5 -5
  66. data/lib/zen/package/menus/lib/menus/controller/menus.rb +4 -4
  67. data/lib/zen/package/menus/lib/menus/helper/menu.rb +4 -4
  68. data/lib/zen/package/menus/lib/menus/model/menu.rb +11 -11
  69. data/lib/zen/package/menus/lib/menus/model/menu_item.rb +10 -10
  70. data/lib/zen/package/menus/lib/menus/public/admin/menus/js/lib/nested_sortables.js +13 -13
  71. data/lib/zen/package/menus/lib/menus/public/admin/menus/js/menu_items.js +1 -1
  72. data/lib/zen/package/sections/lib/sections.rb +19 -0
  73. data/lib/zen/package/sections/lib/sections/controller/revisions.rb +184 -0
  74. data/lib/zen/package/sections/lib/sections/controller/section_entries.rb +5 -5
  75. data/lib/zen/package/sections/lib/sections/controller/sections.rb +9 -6
  76. data/lib/zen/package/sections/lib/sections/helper/revision.rb +124 -0
  77. data/lib/zen/package/sections/lib/sections/helper/section.rb +17 -15
  78. data/lib/zen/package/sections/lib/sections/helper/section_frontend.rb +104 -6
  79. data/lib/zen/package/sections/lib/sections/language/en/revisions.rb +34 -0
  80. data/lib/zen/package/sections/lib/sections/language/en/sections.rb +1 -0
  81. data/lib/zen/package/sections/lib/sections/language/nl/revisions.rb +35 -0
  82. data/lib/zen/package/sections/lib/sections/language/nl/sections.rb +1 -0
  83. data/lib/zen/package/sections/lib/sections/model/revision.rb +76 -0
  84. data/lib/zen/package/sections/lib/sections/model/section.rb +9 -9
  85. data/lib/zen/package/sections/lib/sections/model/section_entry.rb +47 -12
  86. data/lib/zen/package/sections/lib/sections/view/admin/revisions/index.xhtml +89 -0
  87. data/lib/zen/package/sections/lib/sections/view/admin/section-entries/form.xhtml +1 -1
  88. data/lib/zen/package/sections/lib/sections/view/admin/section-entries/index.xhtml +14 -0
  89. data/lib/zen/package/sections/migrations/1335711557_revisions.rb +40 -0
  90. data/lib/zen/package/settings/lib/settings/controller/settings.rb +12 -4
  91. data/lib/zen/package/settings/lib/settings/setting.rb +6 -6
  92. data/lib/zen/package/users/lib/users/controller/user_groups.rb +4 -4
  93. data/lib/zen/package/users/lib/users/controller/users.rb +12 -12
  94. data/lib/zen/package/users/lib/users/helper/access.rb +1 -1
  95. data/lib/zen/package/users/lib/users/helper/acl.rb +4 -4
  96. data/lib/zen/package/users/lib/users/helper/users.rb +2 -2
  97. data/lib/zen/package/users/lib/users/model/permission.rb +1 -1
  98. data/lib/zen/package/users/lib/users/model/user.rb +11 -11
  99. data/lib/zen/package/users/lib/users/model/user_group.rb +9 -9
  100. data/lib/zen/package/users/lib/users/model/user_status.rb +2 -2
  101. data/lib/zen/public/admin/zen/css/general.css +54 -0
  102. data/lib/zen/public/admin/zen/css/messages.css +6 -3
  103. data/lib/zen/public/admin/zen/css/tables.css +10 -0
  104. data/lib/zen/public/admin/zen/images/icons/undo.png +0 -0
  105. data/lib/zen/public/admin/zen/js/lib/autosave.js +8 -8
  106. data/lib/zen/public/admin/zen/js/lib/base.js +2 -2
  107. data/lib/zen/public/admin/zen/js/lib/events.js +2 -2
  108. data/lib/zen/public/admin/zen/js/lib/form.js +7 -7
  109. data/lib/zen/public/admin/zen/js/lib/hash.js +7 -7
  110. data/lib/zen/public/admin/zen/js/lib/tabs.js +3 -3
  111. data/lib/zen/public/admin/zen/js/lib/window.js +1 -1
  112. data/lib/zen/security.rb +2 -2
  113. data/lib/zen/spec/helper.rb +3 -9
  114. data/lib/zen/spec/helper/capybara.rb +4 -4
  115. data/lib/zen/spec/helper/general.rb +1 -1
  116. data/lib/zen/spec/simplecov.rb +1 -5
  117. data/lib/zen/task/build.rake +22 -16
  118. data/lib/zen/task/db.rake +3 -2
  119. data/lib/zen/task/spelling.rake +10 -10
  120. data/lib/zen/task/test.rake +27 -19
  121. data/lib/zen/theme.rb +6 -6
  122. data/lib/zen/version.rb +1 -1
  123. data/spec/zen/all.rb +4 -0
  124. data/spec/zen/package/sections/controller/revisions.rb +235 -0
  125. data/spec/zen/package/sections/model/revision.rb +76 -0
  126. data/zen.gemspec +23 -21
  127. metadata +88 -29
  128. data/lib/zen/model/methods.rb +0 -27
  129. data/lib/zen/task/clean.rake +0 -20
  130. data/lib/zen/task/setup.rake +0 -4
  131. data/pkg/.gitkeep +0 -0
@@ -40,35 +40,35 @@ namespace('Zen');
40
40
  *
41
41
  * hash.getHash(); // => "#!/users/active?limit=10"
42
42
  *
43
- * @since 19-12-2011
43
+ * @since 2011-12-19
44
44
  */
45
45
  Zen.Hash = new Class(
46
46
  {
47
47
  /**
48
48
  * String containing the raw URL hash before it was parsed.
49
49
  *
50
- * @since 19-12-2011
50
+ * @since 2011-12-19
51
51
  */
52
52
  raw_hash: '',
53
53
 
54
54
  /**
55
55
  * Object containing all the parsed hash parameters.
56
56
  *
57
- * @since 19-12-2011
57
+ * @since 2011-12-19
58
58
  */
59
59
  params: {},
60
60
 
61
61
  /**
62
62
  * Array containing all the hash segments.
63
63
  *
64
- * @since 19-12-2011
64
+ * @since 2011-12-19
65
65
  */
66
66
  segments: [],
67
67
 
68
68
  /**
69
69
  * Creates a new instance of the class, sets the raw hash and parses it.
70
70
  *
71
- * @since 19-12-2011
71
+ * @since 2011-12-19
72
72
  * @param {string} hash The URL hash to parse.
73
73
  */
74
74
  initialize: function(hash)
@@ -79,7 +79,7 @@ Zen.Hash = new Class(
79
79
  /**
80
80
  * Parses the supplied hash and stores the results in ``this.params``.
81
81
  *
82
- * @since 19-12-2011
82
+ * @since 2011-12-19
83
83
  * @param {string} hash The hash to parse.
84
84
  */
85
85
  parse: function(hash)
@@ -140,7 +140,7 @@ Zen.Hash = new Class(
140
140
  * Returns a string containing the hash URL for the current segments and
141
141
  * parameters.
142
142
  *
143
- * @since 19-12-2011
143
+ * @since 2011-12-19
144
144
  * @return {string}
145
145
  */
146
146
  getHash: function()
@@ -100,7 +100,7 @@ Zen.Tabs = new Class(
100
100
  * Binds various events to show the right tab fields when a tab is clicked
101
101
  * or when the URL hash is changed.
102
102
  *
103
- * @since 21-12-2011
103
+ * @since 2011-12-21
104
104
  */
105
105
  addEvents: function()
106
106
  {
@@ -134,7 +134,7 @@ Zen.Tabs = new Class(
134
134
  * Determines the default tab field to display based on the option
135
135
  * ``this.options.default`` or the current hash URL.
136
136
  *
137
- * @since 21-12-2011
137
+ * @since 2011-12-21
138
138
  */
139
139
  displayDefault: function()
140
140
  {
@@ -164,7 +164,7 @@ Zen.Tabs = new Class(
164
164
  /**
165
165
  * Activates the tab field for the given ID.
166
166
  *
167
- * @since 21-12-2011
167
+ * @since 2011-12-21
168
168
  * @param {string} id The ID of the tab field to show.
169
169
  */
170
170
  toggleTab: function(id)
@@ -105,7 +105,7 @@ Zen.Window = new Class(
105
105
  /**
106
106
  * The background overlay for the current window.
107
107
  *
108
- * @since 18-12-2011
108
+ * @since 2011-12-18
109
109
  */
110
110
  overlay: null,
111
111
 
@@ -3,7 +3,7 @@ module Zen
3
3
  # Module for dealing with various security related actions such as sanitizing
4
4
  # user input/output.
5
5
  #
6
- # @since 07-01-2012
6
+ # @since 2012-01-07
7
7
  #
8
8
  module Security
9
9
  class << self
@@ -21,7 +21,7 @@ module Zen
21
21
  #
22
22
  # Zen::Input.sanitize(input) # => "Hello \#\{puts 10\}"
23
23
  #
24
- # @since 03-01-2012
24
+ # @since 2012-01-03
25
25
  # @param [String] input The input string to sanitize.
26
26
  # @param [TrueClass|FalseClass] clean_html When set to true certain HTML
27
27
  # elements will be removed using Loofah.
@@ -1,12 +1,6 @@
1
- require 'ramaze'
2
- require 'stringio'
3
-
4
- Ramaze.setup(:verbose => false) do
5
- gem 'capybara', ['>= 1.1.1']
6
- gem 'bacon' , ['>= 1.1.0']
7
- gem 'webmock' , ['>= 1.6.4']
8
- end
9
-
1
+ require 'capybara'
2
+ require 'bacon'
3
+ require 'webmock'
10
4
  require 'capybara/dsl'
11
5
  require 'ramaze/spec/bacon'
12
6
 
@@ -4,7 +4,7 @@ module Zen
4
4
  ##
5
5
  # Module providing various helper methods for Capybara based tests.
6
6
  #
7
- # @since 18-02-2012
7
+ # @since 2012-02-18
8
8
  #
9
9
  module Capybara
10
10
  ##
@@ -30,7 +30,7 @@ module Zen
30
30
  ##
31
31
  # Automatically saves a form with the given ID.
32
32
  #
33
- # @since 18-02-2012
33
+ # @since 2012-02-18
34
34
  # @param [String] id The ID of the form.
35
35
  #
36
36
  def autosave_form(id)
@@ -50,7 +50,7 @@ module Zen
50
50
  ##
51
51
  # Switches Capybara's driver to the default Javascript driver.
52
52
  #
53
- # @since 18-02-2012
53
+ # @since 2012-02-18
54
54
  #
55
55
  def enable_javascript
56
56
  WebMock.disable!
@@ -63,7 +63,7 @@ module Zen
63
63
  ##
64
64
  # Switches Capybara's driver back to the default driver.
65
65
  #
66
- # @since 18-02-2012
66
+ # @since 2012-02-18
67
67
  #
68
68
  def disable_javascript
69
69
  ::Capybara.use_default_driver
@@ -4,7 +4,7 @@ module Zen
4
4
  ##
5
5
  # Module providing general spec helpers.
6
6
  #
7
- # @since 18-02-2012
7
+ # @since 2012-02-18
8
8
  #
9
9
  module General
10
10
  ##
@@ -1,8 +1,4 @@
1
- require 'ramaze'
2
-
3
- Ramaze.setup(:verbose => false) do
4
- gem 'simplecov', ['>= 0.4.2']
5
- end
1
+ require 'simplecov'
6
2
 
7
3
  SimpleCov.configure do
8
4
  root __DIR__('../../../')
@@ -1,23 +1,29 @@
1
1
  namespace :build do
2
- desc 'Build the YARD docs'
3
- task :doc => ['clean:yard'] do
4
- root = File.expand_path('../../../../', __FILE__)
5
- Dir.chdir(root)
2
+ desc 'Generates the Manifest'
3
+ task :manifest do
4
+ files = `git ls-files`.split("\n").sort
5
+ handle = File.open(File.expand_path('../../../../MANIFEST', __FILE__), 'w')
6
6
 
7
- sh('yard doc')
7
+ handle.write(files.join("\n"))
8
+ handle.close
8
9
  end
9
10
 
10
- desc 'Builds a new Gem'
11
- task :gem do
12
- root = File.expand_path('../../../../', __FILE__)
13
- name = "#{Zen::Gemspec.name}-#{Zen::Gemspec.version.version}.gem"
14
- path = File.join(root, name)
15
- pkg = File.join(root, 'pkg', name)
16
-
17
- # Build and install the gem
18
- sh('gem', 'build', File.join(root, 'zen.gemspec'))
19
- sh('mv' , path, pkg)
20
- sh('gem', 'install', pkg)
11
+ desc 'Generates a .gems file for RVM'
12
+ task :gems do
13
+ handle = File.open(File.expand_path('../../../../.gems', __FILE__), 'w')
14
+ run_deps = ['# Runtime Dependencies']
15
+ dev_deps = ['# Development Dependencies']
16
+
17
+ GEMSPEC.dependencies.each do |gem|
18
+ if gem.type == :runtime
19
+ run_deps << gem.name + ' -v ' + gem.requirement.to_s.gsub('~> ', '')
20
+ else
21
+ dev_deps << gem.name
22
+ end
23
+ end
24
+
25
+ handle.write(run_deps.sort.join("\n") + "\n\n" + dev_deps.sort.join("\n"))
26
+ handle.close
21
27
  end
22
28
 
23
29
  desc 'Build a list of changes'
@@ -77,8 +77,9 @@ namespace :db do
77
77
 
78
78
  if group.nil?
79
79
  group = Users::Model::UserGroup.new(
80
- :name => 'Administrators',
81
- :slug => 'administrators', :super_group => true
80
+ :name => 'Administrators',
81
+ :slug => 'administrators',
82
+ :super_group => true
82
83
  ).save
83
84
  end
84
85
 
@@ -1,22 +1,22 @@
1
- # Task that checks the documentation for spelling errors using Raspell/Aspell.
2
- # This task requires Aspell to be installed along with an English dictionary. On
3
- # Arch Linux these can be installed as following:
1
+ # Task that checks the documentation for spelling errors using Aspell. This
2
+ # task requires Aspell to be installed along with an English dictionary. On Arch
3
+ # Linux these can be installed as following:
4
4
  #
5
5
  # $ sudo pacman -S aspell aspell-en
6
6
  #
7
7
  desc 'Search docs for spelling errors'
8
8
  task :spelling do
9
- require 'raspell'
9
+ require 'ffi/aspell'
10
10
  require 'ripper'
11
11
 
12
- speller = Aspell.new1(
13
- 'lang' => 'en',
12
+ speller = FFI::Aspell::Speller.new(
13
+ 'en',
14
14
  'personal' => File.expand_path('../../../../.aspell.en.pws', __FILE__),
15
- 'ignore-case' => 'true'
15
+ 'ignore-case' => true
16
16
  )
17
17
 
18
18
  base_dir = File.expand_path('../../../..', __FILE__)
19
- files = Dir['lib/zen/**/*.rb']
19
+ files = Dir['lib/zen/**/*.rb'] + Dir['guide/**/*.md']
20
20
  exclude_lines = [/^#\s*@/, /^#\s{2,}/, /^#\s*!\[/, /^#\s*\[/]
21
21
  exclude_patterns = [/\d+/, /_+/, /^`/]
22
22
 
@@ -68,8 +68,8 @@ task :spelling do
68
68
 
69
69
  next if skip == true
70
70
 
71
- unless speller.check(word)
72
- suggested = speller.suggest(word)[0]
71
+ unless speller.correct?(word)
72
+ suggested = speller.suggestions(word)[0]
73
73
 
74
74
  if suggested
75
75
  errors << {
@@ -1,40 +1,50 @@
1
1
  namespace :test do
2
- spec_dir = File.expand_path('../../../../spec', __FILE__)
3
- command = 'rake db:delete; rake db:migrate; rake db:test_user; ' \
4
- 'ruby zen/all.rb'
5
-
6
- desc 'Run specifications'
2
+ desc 'Run test using default settings'
7
3
  task :default do
8
- Dir.chdir(spec_dir)
4
+ Dir.chdir(File.expand_path('../../../../spec', __FILE__))
5
+
6
+ sh('rake db:delete')
7
+ sh('rake db:migrate')
8
+ sh('rake db:test_user')
9
9
 
10
- sh(command)
10
+ # Hack to prevent Simplecov from generating code coverage while migrating
11
+ # the database.
12
+ if ENV['_COVERAGE']
13
+ ENV['_COVERAGE'] = nil
14
+ ENV['COVERAGE'] = '1'
15
+ end
16
+
17
+ sh('ruby zen/all.rb')
11
18
  end
12
19
 
13
- desc 'Runs specifications using MySQL'
20
+ desc 'Run tests using MySQL'
14
21
  task :mysql do
15
- Dir.chdir(spec_dir)
16
-
17
22
  ENV['DATABASE'] = 'zen_dev'
18
23
  ENV['ADAPTER'] = 'mysql2'
19
24
  ENV['USERNAME'] = 'zen'
20
25
 
21
- sh(command)
26
+ Rake::Task['test:default'].invoke
22
27
  end
23
28
 
24
- desc 'Runs specifications using PostgreSQL'
29
+ desc 'Run tests using PostgreSQL'
25
30
  task :postgres do
26
- Dir.chdir(spec_dir)
27
-
28
31
  ENV['DATABASE'] = 'zen_dev'
29
32
  ENV['ADAPTER'] = 'postgres'
30
33
  ENV['USERNAME'] = 'zen'
31
34
 
32
- sh(command)
35
+ Rake::Task['test:default'].invoke
36
+ end
37
+
38
+ desc 'Generates code coverage'
39
+ task :coverage do
40
+ ENV['_COVERAGE'] = '1'
41
+
42
+ Rake::Task['test:default'].invoke
33
43
  end
34
44
 
35
45
  # Task that ensures that the various Travis CI tests each use their own
36
46
  # database based on the Ruby version.
37
- desc 'Runs the tests for Travis CI'
47
+ desc 'Run tests for Travis CI'
38
48
  task :travis do
39
49
  suffix = '_' + RUBY_VERSION.gsub('.', '_')
40
50
 
@@ -48,8 +58,6 @@ namespace :test do
48
58
  end
49
59
  end
50
60
 
51
- Dir.chdir(spec_dir)
52
-
53
- sh(command)
61
+ Rake::Task['test:default'].invoke
54
62
  end
55
63
  end
@@ -97,7 +97,7 @@ module Zen
97
97
  #
98
98
  # <div class="note deprecated">
99
99
  # <p>
100
- # <strong>Warning</strong>: Most likely your template will use files
100
+ # <strong>Warning:</strong> Most likely your template will use files
101
101
  # such as CSS and Javascript files. It's important to store these
102
102
  # under their own namespace similar to assets used in the backend to
103
103
  # prevent any collisions.
@@ -257,7 +257,7 @@ module Zen
257
257
  #
258
258
  # <div class="note deprecated">
259
259
  # <p>
260
- # <strong>Warning</strong>: Don't run custom SQL queries inside your
260
+ # <strong>Warning:</strong> Don't run custom SQL queries inside your
261
261
  # templates, create a helper, regular class or module if you want to
262
262
  # retrieve custom data.
263
263
  # </p>
@@ -291,7 +291,7 @@ module Zen
291
291
  #
292
292
  # <div class="note todo">
293
293
  # <p>
294
- # <strong>Note</strong>: The variables set in the partial method are
294
+ # <strong>Note:</strong> The variables set in the partial method are
295
295
  # available as instance variables, not regular variables.
296
296
  # </p>
297
297
  # </div>
@@ -376,7 +376,7 @@ module Zen
376
376
  ##
377
377
  # Creates a new instance of the theme.
378
378
  #
379
- # @since 12-02-2012
379
+ # @since 2012-02-12
380
380
  #
381
381
  def initialize
382
382
  @env = OpenStruct.new
@@ -396,7 +396,7 @@ module Zen
396
396
  # Returns the name of the theme as either plain text or an anchor tag if the
397
397
  # URL attribute is set.
398
398
  #
399
- # @since 19-11-2011
399
+ # @since 2011-11-19
400
400
  # @return [String]
401
401
  #
402
402
  def formatted_name
@@ -430,7 +430,7 @@ module Zen
430
430
  # Returns the name of the default template group or "default" if no custom
431
431
  # name is set.
432
432
  #
433
- # @since 22-11-2011
433
+ # @since 2011-11-22
434
434
  # @return [String]
435
435
  #
436
436
  def default_template_group
@@ -1,4 +1,4 @@
1
1
  module Zen
2
2
  # :nodoc:
3
- VERSION = '0.4.2'
3
+ VERSION = '0.4.3'
4
4
  end
@@ -1,5 +1,9 @@
1
1
  require File.expand_path('../../helper', __FILE__)
2
2
 
3
+ puts "# Ruby version: #{RUBY_VERSION}p#{RUBY_PATCHLEVEL}"
4
+ puts "# Database adapter: #{Zen.database.adapter_scheme}"
5
+ puts "# Database: #{ENV['DATABASE'] || 'SQLite3'}"
6
+
3
7
  Dir.glob(__DIR__ + '/**/*.rb').each do |t|
4
8
  require(t) if File.basename(t) != 'all.rb'
5
9
  end
@@ -0,0 +1,235 @@
1
+ require File.expand_path('../../../../../helper', __FILE__)
2
+
3
+ describe 'Sections::Controller::Revisions' do
4
+ behaves_like :capybara
5
+
6
+ textbox_id = CustomFields::Model::CustomFieldType[:name => 'textbox'].id
7
+ checkbox_id = CustomFields::Model::CustomFieldType[:name => 'checkbox'].id
8
+ section = Sections::Model::Section.create(
9
+ :name => 'Spec section',
10
+ :comment_allow => true,
11
+ :comment_require_account => true,
12
+ :comment_moderate => true,
13
+ :comment_format => 'plain'
14
+ )
15
+
16
+ group = CustomFields::Model::CustomFieldGroup.create(:name => 'Spec fields')
17
+
18
+ field = CustomFields::Model::CustomField.create(
19
+ :name => 'Spec field',
20
+ :sort_order => 0,
21
+ :format => 'markdown',
22
+ :required => true,
23
+ :text_editor => false,
24
+ :custom_field_group_id => group.id,
25
+ :custom_field_type_id => textbox_id
26
+ )
27
+
28
+ field_1 = CustomFields::Model::CustomField.create(
29
+ :name => 'Spec checkbox',
30
+ :sort_order => 1,
31
+ :format => 'plain',
32
+ :required => true,
33
+ :text_editor => false,
34
+ :custom_field_group_id => group.id,
35
+ :custom_field_type_id => checkbox_id,
36
+ :possible_values => "Yorick Peterse|yorick\nChuck Norris|chuck"
37
+ )
38
+
39
+ section.custom_field_group_pks = [group.id]
40
+
41
+ entries_url = Sections::Controller::SectionEntries.r(:index, section.id).to_s
42
+ edit_url = Sections::Controller::SectionEntries.r(:edit, section.id).to_s
43
+ revisions_url = lang('revisions.titles.index')
44
+ restore_url = lang('revisions.labels.restore')
45
+ new_button = lang('section_entries.buttons.new')
46
+ save_button = lang('section_entries.buttons.save')
47
+ compare_button = lang('revisions.buttons.compare')
48
+ title_field = lang('section_entries.labels.title')
49
+
50
+ it 'Create a new revision each time a section entry is saved' do
51
+ visit(entries_url)
52
+
53
+ click_on(new_button)
54
+
55
+ within '#section_entry_form' do
56
+ fill_in(title_field, :with => 'Entry with revisions')
57
+ fill_in(field.name, :with => 'Original value')
58
+ check("form_custom_field_value_#{field_1.id}_0")
59
+
60
+ click_on(save_button)
61
+ end
62
+
63
+ current_path.should =~ /#{edit_url}\/[0-9]+/
64
+ page.has_selector?('.message.error').should == false
65
+
66
+ 9.times do |number|
67
+ within '#section_entry_form' do
68
+ fill_in(field.name, :with => "Modified #{number}")
69
+
70
+ click_on(save_button)
71
+ end
72
+ end
73
+
74
+ page.find_field(field.name).value.should == 'Modified 8'
75
+
76
+ Sections::Model::SectionEntry[:title => 'Entry with revisions'] \
77
+ .revisions.length.should == 10
78
+ end
79
+
80
+ it 'Compare two different revisions' do
81
+ entry = Sections::Model::SectionEntry[:title => 'Entry with revisions']
82
+ url = Sections::Controller::Revisions \
83
+ .r(:index, entry.section_id, entry.id) \
84
+ .to_s
85
+
86
+ revisions = Sections::Model::Revision.filter(:section_entry_id => entry.id) \
87
+ .order(:id.asc) \
88
+ .all
89
+
90
+ visit(entries_url)
91
+ click_on(revisions_url)
92
+
93
+ page.current_path.should == url
94
+ page.all('table tbody tr').count.should == 10
95
+
96
+ choose("old_revision_id_#{revisions[0].id}")
97
+ choose("new_revision_id_#{revisions[1].id}")
98
+
99
+ click_on(compare_button)
100
+
101
+ page.has_selector?('.diff').should == true
102
+ page.has_selector?('.diff .ins').should == true
103
+ page.has_selector?('.diff .del').should == true
104
+ page.has_selector?('.diff .line_number').should == true
105
+
106
+ page.has_content?('Original value').should == true
107
+ page.has_content?('Modified 0').should == true
108
+
109
+ page.find('.diff .del').text.strip.should == '-Original value'
110
+ page.find('.diff .ins').text.strip.should == '+Modified 0'
111
+
112
+ choose("old_revision_id_#{revisions[1].id}")
113
+ choose("new_revision_id_#{revisions[2].id}")
114
+
115
+ click_on(compare_button)
116
+
117
+ page.find('.diff .del').text.strip.should == '-Modified 0'
118
+ page.find('.diff .ins').text.strip.should == '+Modified 1'
119
+ end
120
+
121
+ it 'Compare the same two revisions' do
122
+ entry = Sections::Model::SectionEntry[:title => 'Entry with revisions']
123
+ url = Sections::Controller::Revisions \
124
+ .r(:index, entry.section_id, entry.id) \
125
+ .to_s
126
+
127
+ revisions = Sections::Model::Revision.filter(:section_entry_id => entry.id) \
128
+ .order(:id.asc) \
129
+ .all
130
+
131
+ visit(entries_url)
132
+ click_on(revisions_url)
133
+
134
+ page.current_path.should == url
135
+ page.all('table tbody tr').count.should == 10
136
+
137
+ choose("old_revision_id_#{revisions[0].id}")
138
+ choose("new_revision_id_#{revisions[0].id}")
139
+
140
+ click_on(compare_button)
141
+
142
+ page.has_selector?('.diff').should == false
143
+ page.has_content?(lang('revisions.messages.no_differences')).should == true
144
+ end
145
+
146
+ it 'The oldest revision should be removed if the limit is exceeded' do
147
+ entry = Sections::Model::SectionEntry[:title => 'Entry with revisions']
148
+ oldest = entry.revisions[-1].id
149
+
150
+ visit(entries_url)
151
+
152
+ click_on('Entry with revisions')
153
+
154
+ 5.times do |number|
155
+ within '#section_entry_form' do
156
+ fill_in(field.name, :with => "Overwritten #{number}")
157
+ click_on(save_button)
158
+ end
159
+ end
160
+
161
+ revisions = Sections::Model::Revision.filter(:section_entry_id => entry.id) \
162
+ .order(:id.asc) \
163
+ .all
164
+
165
+ revisions.length.should == 10
166
+ revisions[0].id.should > oldest
167
+ end
168
+
169
+ it 'Gracefully handle non numeric revision IDs' do
170
+ visit(entries_url)
171
+ visit(Sections::Controller::Revisions.r(:restore, 'a').to_s)
172
+
173
+ page.current_path.should == entries_url
174
+ page.has_selector?('.message.error').should == true
175
+ end
176
+
177
+ it 'Restore a revision and delete newer revisions' do
178
+ visit(entries_url)
179
+ click_on(revisions_url)
180
+
181
+ within 'table tbody tr:last-child' do
182
+ click_on(restore_url)
183
+ end
184
+
185
+ page.has_selector?('.message.success').should == true
186
+ page.all('table tbody tr').count.should == 1
187
+
188
+ Sections::Model::SectionEntry[:title => 'Entry with revisions'] \
189
+ .revisions \
190
+ .length \
191
+ .should == 1
192
+
193
+ visit(entries_url)
194
+ click_on('Entry with revisions')
195
+
196
+ page.find_field(field.name).value.should == 'Modified 4'
197
+ end
198
+
199
+ it 'Compare array based values of two revisions' do
200
+ visit(entries_url)
201
+
202
+ click_on('Entry with revisions')
203
+
204
+ within '#section_entry_form' do
205
+ check("form_custom_field_value_#{field_1.id}_1")
206
+ click_on(save_button)
207
+ end
208
+
209
+ page.has_selector?('.message.error').should == false
210
+
211
+ visit(entries_url)
212
+ click_on(revisions_url)
213
+
214
+ entry = Sections::Model::SectionEntry[:title => 'Entry with revisions']
215
+ revisions = Sections::Model::Revision.filter(:section_entry_id => entry.id) \
216
+ .order(:id.asc) \
217
+ .all
218
+
219
+ choose("old_revision_id_#{revisions[-1].id}")
220
+ choose("new_revision_id_#{revisions[-2].id}")
221
+
222
+ click_on(compare_button)
223
+
224
+ page.has_selector?('.diff .ins').should == false
225
+ page.has_selector?('.diff .del').should == true
226
+
227
+ page.has_content?('yorick').should == true
228
+ page.has_content?('chuck').should == true
229
+ end
230
+
231
+ field.destroy
232
+ field_1.destroy
233
+ group.destroy
234
+ section.destroy
235
+ end