adva_cms 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/NOTES +132 -0
- data/README.md +29 -0
- data/Rakefile +2 -0
- data/adva_cms.gemspec +22 -0
- data/app/assets/images/adva_cms/admin/header_bg.png +0 -0
- data/app/assets/images/adva_cms/admin/section_menu_bg.png +0 -0
- data/app/assets/images/adva_cms/admin/tab_action_active.png +0 -0
- data/app/assets/images/adva_cms/admin/tab_main_active.png +0 -0
- data/app/assets/images/adva_cms/admin/tab_sidebar_active.png +0 -0
- data/app/assets/images/adva_cms/admin/tab_top_active.png +0 -0
- data/app/assets/images/adva_cms/asset_selected.png +0 -0
- data/app/assets/images/adva_cms/avatar.gif +0 -0
- data/app/assets/images/adva_cms/filter-bg.png +0 -0
- data/app/assets/images/adva_cms/icons/accept.png +0 -0
- data/app/assets/images/adva_cms/icons/add.png +0 -0
- data/app/assets/images/adva_cms/icons/arrow_cross.png +0 -0
- data/app/assets/images/adva_cms/icons/arrow_cross_2.png +0 -0
- data/app/assets/images/adva_cms/icons/arrow_cross_3.png +0 -0
- data/app/assets/images/adva_cms/icons/arrow_up_down.png +0 -0
- data/app/assets/images/adva_cms/icons/assets/audio.png +0 -0
- data/app/assets/images/adva_cms/icons/assets/doc.png +0 -0
- data/app/assets/images/adva_cms/icons/assets/pdf.png +0 -0
- data/app/assets/images/adva_cms/icons/assets/video.png +0 -0
- data/app/assets/images/adva_cms/icons/attach.png +0 -0
- data/app/assets/images/adva_cms/icons/bin.png +0 -0
- data/app/assets/images/adva_cms/icons/bin_closed.png +0 -0
- data/app/assets/images/adva_cms/icons/bin_empty.png +0 -0
- data/app/assets/images/adva_cms/icons/bullet_black.png +0 -0
- data/app/assets/images/adva_cms/icons/bullet_delete.png +0 -0
- data/app/assets/images/adva_cms/icons/bullet_error.png +0 -0
- data/app/assets/images/adva_cms/icons/bullet_go.png +0 -0
- data/app/assets/images/adva_cms/icons/bullet_red.png +0 -0
- data/app/assets/images/adva_cms/icons/bullet_white.png +0 -0
- data/app/assets/images/adva_cms/icons/bullet_yellow.png +0 -0
- data/app/assets/images/adva_cms/icons/cancel.png +0 -0
- data/app/assets/images/adva_cms/icons/comment.gif +0 -0
- data/app/assets/images/adva_cms/icons/comment.png +0 -0
- data/app/assets/images/adva_cms/icons/comment_add.png +0 -0
- data/app/assets/images/adva_cms/icons/comment_blue.gif +0 -0
- data/app/assets/images/adva_cms/icons/comment_delete.png +0 -0
- data/app/assets/images/adva_cms/icons/comment_edit.png +0 -0
- data/app/assets/images/adva_cms/icons/comment_yellow.gif +0 -0
- data/app/assets/images/adva_cms/icons/cross.png +0 -0
- data/app/assets/images/adva_cms/icons/delete.png +0 -0
- data/app/assets/images/adva_cms/icons/eye.png +0 -0
- data/app/assets/images/adva_cms/icons/favorites.png +0 -0
- data/app/assets/images/adva_cms/icons/help.png +0 -0
- data/app/assets/images/adva_cms/icons/hourglass.png +0 -0
- data/app/assets/images/adva_cms/icons/icon_attachment.gif +0 -0
- data/app/assets/images/adva_cms/icons/icon_padlock.gif +0 -0
- data/app/assets/images/adva_cms/icons/link.png +0 -0
- data/app/assets/images/adva_cms/icons/lock.png +0 -0
- data/app/assets/images/adva_cms/icons/magnifier.png +0 -0
- data/app/assets/images/adva_cms/icons/minus.gif +0 -0
- data/app/assets/images/adva_cms/icons/page_add.png +0 -0
- data/app/assets/images/adva_cms/icons/page_delete.png +0 -0
- data/app/assets/images/adva_cms/icons/page_edit.png +0 -0
- data/app/assets/images/adva_cms/icons/page_favorites.png +0 -0
- data/app/assets/images/adva_cms/icons/page_go.png +0 -0
- data/app/assets/images/adva_cms/icons/page_green.png +0 -0
- data/app/assets/images/adva_cms/icons/page_red.png +0 -0
- data/app/assets/images/adva_cms/icons/page_white_add.png +0 -0
- data/app/assets/images/adva_cms/icons/page_white_delete.png +0 -0
- data/app/assets/images/adva_cms/icons/page_white_edit.png +0 -0
- data/app/assets/images/adva_cms/icons/page_white_go.png +0 -0
- data/app/assets/images/adva_cms/icons/page_white_link.png +0 -0
- data/app/assets/images/adva_cms/icons/page_white_magnify.png +0 -0
- data/app/assets/images/adva_cms/icons/pencil.png +0 -0
- data/app/assets/images/adva_cms/icons/star.png +0 -0
- data/app/assets/images/adva_cms/icons/stop.png +0 -0
- data/app/assets/images/adva_cms/icons/tag_green.png +0 -0
- data/app/assets/images/adva_cms/icons/tick.png +0 -0
- data/app/assets/images/adva_cms/icons/zoom.png +0 -0
- data/app/assets/images/adva_cms/indicator.gif +0 -0
- data/app/assets/images/adva_cms/preview.png +0 -0
- data/app/assets/images/adva_cms/rails.png +0 -0
- data/app/assets/images/adva_cms/sortable_tree/drag.png +0 -0
- data/app/assets/images/adva_cms/theme_selected.png +0 -0
- data/app/assets/javascripts/admin.js +1 -0
- data/app/assets/javascripts/adva_cms/admin/jquery.admin.js +23 -0
- data/app/assets/javascripts/adva_cms/admin/jquery.article.js +22 -0
- data/app/assets/javascripts/adva_cms/admin/jquery.cached_pages.js +14 -0
- data/app/assets/javascripts/adva_cms/admin/jquery.table_tree.js +7 -0
- data/app/assets/javascripts/adva_cms/application.js +14 -0
- data/app/assets/javascripts/adva_cms/base.js +4 -0
- data/app/assets/javascripts/adva_cms/cookie.js +49 -0
- data/app/assets/javascripts/adva_cms/jquery.common.js +41 -0
- data/app/assets/javascripts/adva_cms/jquery.dates.js +51 -0
- data/app/assets/javascripts/adva_cms/jquery.flash.js +57 -0
- data/app/assets/javascripts/adva_cms/jquery.roles.js +25 -0
- data/app/assets/javascripts/adva_cms/jquery/jquery-lowpro.js +224 -0
- data/app/assets/javascripts/adva_cms/jquery/jquery.qtip.js +2085 -0
- data/app/assets/javascripts/adva_cms/jquery/jquery.table_tree.js +307 -0
- data/app/assets/javascripts/adva_cms/jquery/jquery.tablednd_0_5.js +386 -0
- data/app/assets/javascripts/adva_cms/json.js +139 -0
- data/app/assets/stylesheets/admin.css +1 -0
- data/app/assets/stylesheets/adva_cms/admin.css +16 -0
- data/app/assets/stylesheets/adva_cms/admin/alternate/common.css +76 -0
- data/app/assets/stylesheets/adva_cms/admin/alternate/forms.css +121 -0
- data/app/assets/stylesheets/adva_cms/admin/alternate/header.css +125 -0
- data/app/assets/stylesheets/adva_cms/admin/alternate/layout.css +103 -0
- data/app/assets/stylesheets/adva_cms/admin/alternate/lists.css +153 -0
- data/app/assets/stylesheets/adva_cms/admin/alternate/sidebar.css +65 -0
- data/app/assets/stylesheets/adva_cms/admin/alternate/top.css +123 -0
- data/app/assets/stylesheets/adva_cms/admin/common.css +76 -0
- data/app/assets/stylesheets/adva_cms/admin/content.css +11 -0
- data/app/assets/stylesheets/adva_cms/admin/forms.css +116 -0
- data/app/assets/stylesheets/adva_cms/admin/header.css +114 -0
- data/app/assets/stylesheets/adva_cms/admin/helptip.css +35 -0
- data/app/assets/stylesheets/adva_cms/admin/layout.css +56 -0
- data/app/assets/stylesheets/adva_cms/admin/lists.css +152 -0
- data/app/assets/stylesheets/adva_cms/admin/projection.css +118 -0
- data/app/assets/stylesheets/adva_cms/admin/reset.css +25 -0
- data/app/assets/stylesheets/adva_cms/admin/screen/top.css +8 -0
- data/app/assets/stylesheets/adva_cms/admin/sidebar.css +67 -0
- data/app/assets/stylesheets/adva_cms/admin/themes.css +49 -0
- data/app/assets/stylesheets/adva_cms/admin/top.css +83 -0
- data/app/assets/stylesheets/adva_cms/admin/users.css +40 -0
- data/app/assets/stylesheets/adva_cms/common.css +49 -0
- data/app/assets/stylesheets/adva_cms/default.css +201 -0
- data/app/assets/stylesheets/adva_cms/forms.css +60 -0
- data/app/assets/stylesheets/adva_cms/jquery/alternate/jquery.tooltip.css +13 -0
- data/app/assets/stylesheets/adva_cms/jquery/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/app/assets/stylesheets/adva_cms/jquery/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/app/assets/stylesheets/adva_cms/jquery/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/app/assets/stylesheets/adva_cms/jquery/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/app/assets/stylesheets/adva_cms/jquery/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/app/assets/stylesheets/adva_cms/jquery/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/app/assets/stylesheets/adva_cms/jquery/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/app/assets/stylesheets/adva_cms/jquery/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/app/assets/stylesheets/adva_cms/jquery/images/ui-icons_222222_256x240.png +0 -0
- data/app/assets/stylesheets/adva_cms/jquery/images/ui-icons_2e83ff_256x240.png +0 -0
- data/app/assets/stylesheets/adva_cms/jquery/images/ui-icons_454545_256x240.png +0 -0
- data/app/assets/stylesheets/adva_cms/jquery/images/ui-icons_888888_256x240.png +0 -0
- data/app/assets/stylesheets/adva_cms/jquery/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/app/assets/stylesheets/adva_cms/jquery/jquery-ui.css +406 -0
- data/app/assets/stylesheets/adva_cms/jquery/jquery.tooltip.css +10 -0
- data/app/assets/stylesheets/adva_cms/layout/login.css +8 -0
- data/app/assets/stylesheets/adva_cms/layout/simple.css +8 -0
- data/app/assets/stylesheets/adva_cms/menu.css +129 -0
- data/app/assets/stylesheets/adva_cms/reset.css +25 -0
- data/app/controllers/admin/base_controller.rb +101 -0
- data/app/controllers/admin/categories_controller.rb +3 -0
- data/app/controllers/admin/install_controller.rb +61 -0
- data/app/controllers/admin/page/articles_controller.rb +150 -0
- data/app/controllers/admin/page/categories_controller.rb +62 -0
- data/app/controllers/admin/page/contents_controller.rb +52 -0
- data/app/controllers/admin/page/links_controller.rb +69 -0
- data/app/controllers/admin/pages_controller.rb +2 -0
- data/app/controllers/admin/plugins_controller.rb +40 -0
- data/app/controllers/admin/sections_controller.rb +91 -0
- data/app/controllers/admin/sites_controller.rb +99 -0
- data/app/controllers/articles_controller.rb +81 -0
- data/app/controllers/base_controller.rb +82 -0
- data/app/helpers/admin/base_helper.rb +106 -0
- data/app/helpers/base_helper.rb +56 -0
- data/app/helpers/content_helper.rb +90 -0
- data/app/helpers/resource_helper.rb +127 -0
- data/app/models/article.rb +40 -0
- data/app/models/categorization.rb +4 -0
- data/app/models/category.rb +60 -0
- data/app/models/content.rb +155 -0
- data/app/models/event.rb +34 -0
- data/app/models/link.rb +4 -0
- data/app/models/page.rb +36 -0
- data/app/models/section.rb +126 -0
- data/app/models/site.rb +104 -0
- data/app/views/admin/cached_pages/_filter.html.erb +8 -0
- data/app/views/admin/cached_pages/destroy.js.erb +18 -0
- data/app/views/admin/cached_pages/index.html.erb +26 -0
- data/app/views/admin/install/confirmation.html.erb +10 -0
- data/app/views/admin/install/index.html.erb +38 -0
- data/app/views/admin/page/articles/_form.html.erb +40 -0
- data/app/views/admin/page/articles/_options.html.erb +20 -0
- data/app/views/admin/page/articles/edit.html.erb +15 -0
- data/app/views/admin/page/articles/new.html.erb +12 -0
- data/app/views/admin/page/categories/edit.html.erb +22 -0
- data/app/views/admin/page/categories/index.html.erb +23 -0
- data/app/views/admin/page/categories/new.html.erb +19 -0
- data/app/views/admin/page/contents/index.html.erb +40 -0
- data/app/views/admin/page/links/_form.html.erb +26 -0
- data/app/views/admin/page/links/_options.html.erb +23 -0
- data/app/views/admin/page/links/edit.html.erb +12 -0
- data/app/views/admin/page/links/new.html.erb +12 -0
- data/app/views/admin/plugins/_form.html.erb +11 -0
- data/app/views/admin/plugins/index.html.erb +16 -0
- data/app/views/admin/plugins/show.html.erb +43 -0
- data/app/views/admin/sections/_form.html.haml +20 -0
- data/app/views/admin/sections/edit.html.haml +6 -0
- data/app/views/admin/sections/index.html.erb +27 -0
- data/app/views/admin/sections/new.html.erb +29 -0
- data/app/views/admin/sections/settings/_page.html.haml +10 -0
- data/app/views/admin/shared/_header.html.erb +18 -0
- data/app/views/admin/shared/_language_select.html.erb +6 -0
- data/app/views/admin/shared/_section.html.erb +8 -0
- data/app/views/admin/shared/_section_summary.html.erb +23 -0
- data/app/views/admin/shared/_section_tree.html.erb +23 -0
- data/app/views/admin/sites/_email_notifications.html.erb +9 -0
- data/app/views/admin/sites/_form.html.erb +15 -0
- data/app/views/admin/sites/_recent_users.html.erb +11 -0
- data/app/views/admin/sites/_sections.html.erb +10 -0
- data/app/views/admin/sites/_unapproved_comments.html.erb +10 -0
- data/app/views/admin/sites/edit.html.erb +4 -0
- data/app/views/admin/sites/index.html.erb +21 -0
- data/app/views/admin/sites/multi_sites_disabled.html.erb +11 -0
- data/app/views/admin/sites/new.html.erb +21 -0
- data/app/views/admin/sites/show.html.erb +16 -0
- data/app/views/categories/_checkboxes.html.erb +12 -0
- data/app/views/layouts/admin.html.haml +50 -0
- data/app/views/layouts/default.html.erb +38 -0
- data/app/views/layouts/simple.html.erb +22 -0
- data/app/views/pages/articles/index.html.erb +10 -0
- data/app/views/pages/articles/show.html.erb +17 -0
- data/app/views/shared/_flash.html.erb +3 -0
- data/app/views/shared/_footer.html.erb +4 -0
- data/app/views/shared/_menu.html.erb +10 -0
- data/app/views/shared/_sidebar.html.erb +19 -0
- data/app/views/shared/messages/insufficient_permissions.html.erb +4 -0
- data/config/environment.rb +21 -0
- data/config/initializers/has_options.rb +2 -0
- data/config/initializers/has_permalink.rb +27 -0
- data/config/initializers/mailer.rb +12 -0
- data/config/initializers/menus.rb +184 -0
- data/config/initializers/roles.rb +91 -0
- data/config/initializers/settings.rb +26 -0
- data/config/initializers/site.rb +5 -0
- data/config/initializers/translations_are_a_pain.rb +9 -0
- data/config/locales/en.yml +1295 -0
- data/config/routes.rb +47 -0
- data/db/migrate/20080401000001_create_sites_table.rb +28 -0
- data/db/migrate/20080401000002_create_sections_table.rb +25 -0
- data/db/migrate/20080401000003_create_contents_table.rb +35 -0
- data/db/migrate/20080401000004_create_categories_table.rb +17 -0
- data/db/migrate/20080401000005_create_category_assignments.rb +12 -0
- data/db/migrate/20080401000006_create_taggable_tables.rb +26 -0
- data/db/migrate/20080710000000_create_plugin_configs.rb +13 -0
- data/db/migrate/20080715131051_plugin_owner_column.rb +13 -0
- data/db/migrate/20081208161500_add_content_type_to_join_tables.rb +10 -0
- data/db/migrate/20090216114034_rename_category_assignment_to_categorization.rb +13 -0
- data/db/migrate/20090305123429_move_sections_to_pages.rb +9 -0
- data/db/migrate/20090519132700_add_published_at_to_sections.rb +10 -0
- data/db/migrate/20090702085459_create_section_translations.rb +9 -0
- data/db/migrate/20090702200226_create_category_translations.rb +9 -0
- data/db/migrate/20090707171100_upgrade_paperclip_paths.rb +31 -0
- data/db/migrate/20090709111934_add_email_notification_to_site.rb +12 -0
- data/db/migrate/20091026000906_add_nesting_to_articles.rb +26 -0
- data/db/migrate/20140721000000_add_title_to_contents.rb +7 -0
- data/lib/adva_cms.rb +50 -0
- data/lib/adva_cms/version.rb +3 -0
- data/lib/core_ext.rb +7 -0
- data/lib/extensible_forms.rb +283 -0
- data/lib/has_options.rb +46 -0
- data/lib/html_diff.rb +48 -0
- data/lib/rails_ext.rb +15 -0
- data/lib/rails_ext/action_controller/cacheable_flash.rb +30 -0
- data/lib/rails_ext/action_controller/content_for_assignments.rb +105 -0
- data/lib/rails_ext/action_controller/default_params.rb +19 -0
- data/lib/rails_ext/action_controller/event_helper.rb +18 -0
- data/lib/rails_ext/action_controller/page_caching.rb +23 -0
- data/lib/rails_ext/action_controller/render_with_error_proc.rb +46 -0
- data/lib/rails_ext/action_controller/responds_to_parent.rb +46 -0
- data/lib/rails_ext/action_controller/url_for_returning.rb +12 -0
- data/lib/rails_ext/active_record/exists.rb +5 -0
- data/lib/rails_ext/active_record/sti_instantiation.rb +35 -0
- data/lib/rails_ext/active_record/sticky_changes.rb +30 -0
- data/lib/rails_ext/railties/plugin.rb +58 -0
- data/lib/rails_ext/railties/plugin_configuration.rb +72 -0
- data/lib/rails_ext/railties/plugin_initializers.rb +25 -0
- data/lib/registry.rb +49 -0
- data/lib/tasks/adva_cms.rake +178 -0
- data/lib/tasks/translation.rake +69 -0
- data/lib/time_hacks.rb +57 -0
- data/lib/webrat_patch.rb +11 -0
- data/locale/rails/fr.yml +123 -0
- data/test/NOTES +56 -0
- data/test/contexts.rb +365 -0
- data/test/fixtures.rb +190 -0
- data/test/fixtures/templates/alternative_templates/index.html.erb +1 -0
- data/test/fixtures/templates/context_templates_test/index.html.erb +1 -0
- data/test/fixtures/templates/context_templates_test/show.html.erb +0 -0
- data/test/fixtures/templates/layouts/alternative.html.erb +0 -0
- data/test/fixtures/templates/layouts/default.html.erb +0 -0
- data/test/fixtures/templates/menu/shared/_menu.html.erb +8 -0
- data/test/functional/admin/articles_controller_test.rb +329 -0
- data/test/functional/admin/base_controller_test.rb +68 -0
- data/test/functional/admin/cached_pages_controller_test.rb +66 -0
- data/test/functional/admin/categories_controller_test.rb +164 -0
- data/test/functional/admin/cells_controller_spec.rb +32 -0
- data/test/functional/admin/install_controller_test.rb +89 -0
- data/test/functional/admin/plugins_controller_test.rb +93 -0
- data/test/functional/admin/sections_controller_test.rb +201 -0
- data/test/functional/admin/sites_controller_test.rb +240 -0
- data/test/functional/asset_tag_expansions_test.rb +82 -0
- data/test/functional/base_controller_test.rb +73 -0
- data/test/functional/page_articles_controller_test.rb +168 -0
- data/test/functional/page_articles_routes_test.rb +73 -0
- data/test/integration/admin/cached_pages_test.rb +43 -0
- data/test/integration/admin/categories_test.rb +66 -0
- data/test/integration/admin/custom_templates_test.rb +42 -0
- data/test/integration/admin/filtering_articles_test.rb +32 -0
- data/test/integration/admin/plugins.rb +32 -0
- data/test/integration/admin/section_article_test.rb +150 -0
- data/test/integration/admin/section_test.rb +88 -0
- data/test/integration/admin/sites_test.rb +48 -0
- data/test/integration/installation_test.rb +109 -0
- data/test/integration/page_article_comment_test.rb +51 -0
- data/test/integration/page_article_test.rb +87 -0
- data/test/integration/section_index_test.rb +37 -0
- data/test/javascript/assets/jquery-lowpro.js +224 -0
- data/test/javascript/assets/jquery-ui.js +298 -0
- data/test/javascript/assets/jquery.js +4376 -0
- data/test/javascript/assets/testrunner.js +815 -0
- data/test/javascript/assets/testsuite.css +120 -0
- data/test/javascript/lib/jstest.rb +588 -0
- data/test/javascript/templates/test_case.erb +33 -0
- data/test/plugins/adva_context_templates/context_templates_test.rb +138 -0
- data/test/plugins/adva_post_ping/controller/integration_test.rb +78 -0
- data/test/plugins/adva_post_ping/post_ping_test.rb +94 -0
- data/test/plugins/adva_url_history/article_test.rb +94 -0
- data/test/plugins/adva_url_history/init_url_history.rb +18 -0
- data/test/plugins/adva_url_history/section_test.rb +49 -0
- data/test/test_helper.rb +75 -0
- data/test/test_helper/clear_directories.rb +16 -0
- data/test/test_helper/ensure_single_site_mode.rb +10 -0
- data/test/test_helper/extensions/cacheable_flash.rb +14 -0
- data/test/test_helper/extensions/cronjob.rb +11 -0
- data/test/test_helper/extensions/even_test_log.rb +21 -0
- data/test/test_helper/extensions/integration_test.rb +78 -0
- data/test/test_helper/extensions/matchy.rb +365 -0
- data/test/test_helper/extensions/matchy_adva_cms.rb +441 -0
- data/test/test_helper/extensions/rails_patch.rb +40 -0
- data/test/test_helper/extensions/rr.rb +7 -0
- data/test/test_helper/extensions/test_unit.rb +35 -0
- data/test/test_helper/extensions/with_sugar.rb +166 -0
- data/test/test_helper/parse_options.rb +18 -0
- data/test/test_helper/setup_db_transaction.rb +15 -0
- data/test/test_helper/setup_webrat.rb +9 -0
- data/test/test_helper/test_server/init.rb +15 -0
- data/test/unit/helpers/admin/base_helper_test.rb +139 -0
- data/test/unit/helpers/base_helper_spec.rb +54 -0
- data/test/unit/helpers/base_helper_test.rb +165 -0
- data/test/unit/helpers/content_helper_test.rb +127 -0
- data/test/unit/helpers/resource_helper_test.rb +180 -0
- data/test/unit/i18n_test.rb +22 -0
- data/test/unit/lib/cells_ext_spec.rb +96 -0
- data/test/unit/lib/extensible_forms_test.rb +362 -0
- data/test/unit/lib/menu_test.rb +119 -0
- data/test/unit/lib/rails_ext/content_for_assignments_test.rb +75 -0
- data/test/unit/lib/rails_ext/plugin_configuration_test.rb +40 -0
- data/test/unit/lib/rails_ext/sticky_changes_test.rb +33 -0
- data/test/unit/lib/registry_test.rb +91 -0
- data/test/unit/lib/routing_filter/routing_filter_categories_spec.rb +63 -0
- data/test/unit/lib/routing_filter/routing_filter_categories_test.rb +159 -0
- data/test/unit/lib/routing_filter/routing_filter_locale_spec.rb +73 -0
- data/test/unit/lib/routing_filter/routing_filter_root_blog_archive_spec.rb +40 -0
- data/test/unit/lib/routing_filter/routing_filter_root_section_articles_spec.rb +48 -0
- data/test/unit/lib/routing_filter/routing_filter_root_wikipages_spec.rb +40 -0
- data/test/unit/lib/routing_filter/routing_filter_sections_spec.rb +143 -0
- data/test/unit/lib/routing_filter/routing_filter_sections_test.rb +32 -0
- data/test/unit/lib/routing_filter/routing_filter_sets_test.rb +86 -0
- data/test/unit/models/article_test.rb +191 -0
- data/test/unit/models/category_test.rb +68 -0
- data/test/unit/models/content_test.rb +409 -0
- data/test/unit/models/counter_test.rb +43 -0
- data/test/unit/models/event_test.rb +41 -0
- data/test/unit/models/nested_categories_test.rb +34 -0
- data/test/unit/models/page_test.rb +63 -0
- data/test/unit/models/section_test.rb +315 -0
- data/test/unit/models/site_test.rb +199 -0
- data/test/unit/observers/activities_article_observer_test.rb +42 -0
- data/vendor/gems/belongs_to_cacheable/.gitignore +17 -0
- data/vendor/gems/belongs_to_cacheable/Gemfile +4 -0
- data/vendor/gems/belongs_to_cacheable/LICENSE +22 -0
- data/vendor/gems/belongs_to_cacheable/README.md +29 -0
- data/vendor/gems/belongs_to_cacheable/Rakefile +2 -0
- data/vendor/gems/belongs_to_cacheable/belongs_to_cacheable.gemspec +22 -0
- data/vendor/gems/belongs_to_cacheable/init.rb +1 -0
- data/vendor/gems/belongs_to_cacheable/lib/active_record/belongs_to_cacheable.rb +77 -0
- data/vendor/gems/belongs_to_cacheable/lib/belongs_to_cacheable.rb +3 -0
- data/vendor/gems/belongs_to_cacheable/lib/belongs_to_cacheable/version.rb +3 -0
- data/vendor/gems/belongs_to_cacheable/spec/belongs_to_cacheable_spec.rb +52 -0
- data/vendor/gems/belongs_to_cacheable/spec/spec_helper.rb +50 -0
- data/vendor/gems/filtered_column/.gitignore +17 -0
- data/vendor/gems/filtered_column/Gemfile +4 -0
- data/vendor/gems/filtered_column/LICENSE +22 -0
- data/vendor/gems/filtered_column/README +4 -0
- data/vendor/gems/filtered_column/README.md +29 -0
- data/vendor/gems/filtered_column/Rakefile +23 -0
- data/vendor/gems/filtered_column/filtered_column.gemspec +17 -0
- data/vendor/gems/filtered_column/lib/filtered_column.rb +17 -0
- data/vendor/gems/filtered_column/lib/filtered_column/filters/base.rb +28 -0
- data/vendor/gems/filtered_column/lib/filtered_column/filters/smartypants_filter.rb +14 -0
- data/vendor/gems/filtered_column/lib/filtered_column/filters/textile_filter.rb +13 -0
- data/vendor/gems/filtered_column/lib/filtered_column/macros/base.rb +25 -0
- data/vendor/gems/filtered_column/lib/filtered_column/mixin.rb +46 -0
- data/vendor/gems/filtered_column/lib/filtered_column/processor.rb +52 -0
- data/vendor/gems/filtered_column/lib/filtered_column/version.rb +3 -0
- data/vendor/gems/filtered_column/tasks/filtered_column_tasks.rake +4 -0
- data/vendor/gems/filtered_column/test/abstract_unit.rb +73 -0
- data/vendor/gems/filtered_column/test/filtered_column_test.rb +53 -0
- data/vendor/gems/filtered_column/test/macro_filter_test.rb +23 -0
- data/vendor/gems/has_counter/.gitignore +17 -0
- data/vendor/gems/has_counter/Gemfile +4 -0
- data/vendor/gems/has_counter/LICENSE +22 -0
- data/vendor/gems/has_counter/MIT-LICENSE +20 -0
- data/vendor/gems/has_counter/README.markdown +64 -0
- data/vendor/gems/has_counter/README.md +29 -0
- data/vendor/gems/has_counter/Rakefile +2 -0
- data/vendor/gems/has_counter/db/migrate/20080601194338_create_counters_table.rb.rb +13 -0
- data/vendor/gems/has_counter/has_counter.gemspec +17 -0
- data/vendor/gems/has_counter/lib/active_record/has_counter.rb +64 -0
- data/vendor/gems/has_counter/lib/counter.rb +23 -0
- data/vendor/gems/has_counter/lib/has_counter.rb +4 -0
- data/vendor/gems/has_counter/lib/has_counter/version.rb +3 -0
- data/vendor/gems/has_counter/spec/has_counter.spec.log +0 -0
- data/vendor/gems/has_counter/spec/has_counter.sqlite3.db +0 -0
- data/vendor/gems/has_counter/spec/has_counter_spec.rb +55 -0
- data/vendor/gems/has_counter/spec/spec_helper.rb +117 -0
- data/vendor/gems/has_filter/.gitignore +17 -0
- data/vendor/gems/has_filter/Gemfile +4 -0
- data/vendor/gems/has_filter/LICENSE +22 -0
- data/vendor/gems/has_filter/README.md +29 -0
- data/vendor/gems/has_filter/Rakefile +2 -0
- data/vendor/gems/has_filter/app/assets/images/has_filter/filter_add.png +0 -0
- data/vendor/gems/has_filter/app/assets/images/has_filter/filter_button_left.png +0 -0
- data/vendor/gems/has_filter/app/assets/images/has_filter/filter_button_right.png +0 -0
- data/vendor/gems/has_filter/app/assets/images/has_filter/filter_remove.png +0 -0
- data/vendor/gems/has_filter/app/assets/javascripts/has_filter/filter.js +35 -0
- data/vendor/gems/has_filter/app/assets/javascripts/has_filter/jquery.filter.js +23 -0
- data/vendor/gems/has_filter/app/assets/stylesheets/has_filter/alternate/filter.css +102 -0
- data/vendor/gems/has_filter/app/assets/stylesheets/has_filter/filter.css +100 -0
- data/vendor/gems/has_filter/app/helpers/filter_helper.rb +3 -0
- data/vendor/gems/has_filter/has_filter.gemspec +17 -0
- data/vendor/gems/has_filter/init.rb +3 -0
- data/vendor/gems/has_filter/lib/has_filter.rb +22 -0
- data/vendor/gems/has_filter/lib/has_filter/active_record/act_macro.rb +102 -0
- data/vendor/gems/has_filter/lib/has_filter/filter.rb +17 -0
- data/vendor/gems/has_filter/lib/has_filter/filter/base.rb +67 -0
- data/vendor/gems/has_filter/lib/has_filter/filter/categorized.rb +24 -0
- data/vendor/gems/has_filter/lib/has_filter/filter/chain.rb +45 -0
- data/vendor/gems/has_filter/lib/has_filter/filter/set.rb +80 -0
- data/vendor/gems/has_filter/lib/has_filter/filter/state.rb +25 -0
- data/vendor/gems/has_filter/lib/has_filter/filter/tagged.rb +22 -0
- data/vendor/gems/has_filter/lib/has_filter/filter/text.rb +55 -0
- data/vendor/gems/has_filter/lib/has_filter/version.rb +3 -0
- data/vendor/gems/has_filter/test/db/setup.rb +45 -0
- data/vendor/gems/has_filter/test/db/test.sqlite3.db +0 -0
- data/vendor/gems/has_filter/test/fixtures.rb +15 -0
- data/vendor/gems/has_filter/test/has_filter/filter_chain_test.rb +41 -0
- data/vendor/gems/has_filter/test/has_filter/filter_scopes_test.rb +102 -0
- data/vendor/gems/has_filter/test/has_filter/filter_tags_test.rb +113 -0
- data/vendor/gems/has_filter/test/has_filter/integration.rb +15 -0
- data/vendor/gems/has_filter/test/has_filter/scopes_test.rb +48 -0
- data/vendor/gems/has_filter/test/log/test.log +34346 -0
- data/vendor/gems/has_filter/test/models.rb +23 -0
- data/vendor/gems/has_filter/test/templates/has_filter/test/index.html.erb +5 -0
- data/vendor/gems/has_filter/test/test_helper.rb +66 -0
- data/vendor/gems/simple_taggable/.gitignore +17 -0
- data/vendor/gems/simple_taggable/Gemfile +4 -0
- data/vendor/gems/simple_taggable/LICENSE +22 -0
- data/vendor/gems/simple_taggable/README +24 -0
- data/vendor/gems/simple_taggable/README.md +29 -0
- data/vendor/gems/simple_taggable/Rakefile +2 -0
- data/vendor/gems/simple_taggable/lib/simple_taggable.rb +153 -0
- data/vendor/gems/simple_taggable/lib/simple_taggable/version.rb +3 -0
- data/vendor/gems/simple_taggable/lib/tag.rb +31 -0
- data/vendor/gems/simple_taggable/lib/tag_list.rb +90 -0
- data/vendor/gems/simple_taggable/lib/tagging.rb +8 -0
- data/vendor/gems/simple_taggable/simple_taggable.gemspec +17 -0
- data/vendor/gems/simple_taggable/test/db/schema.rb +41 -0
- data/vendor/gems/simple_taggable/test/db/simple_taggable.sqlite3.db +0 -0
- data/vendor/gems/simple_taggable/test/fixtures/magazine.rb +3 -0
- data/vendor/gems/simple_taggable/test/fixtures/magazines.yml +2 -0
- data/vendor/gems/simple_taggable/test/fixtures/photo.rb +8 -0
- data/vendor/gems/simple_taggable/test/fixtures/photos.yml +19 -0
- data/vendor/gems/simple_taggable/test/fixtures/post.rb +5 -0
- data/vendor/gems/simple_taggable/test/fixtures/posts.yml +27 -0
- data/vendor/gems/simple_taggable/test/fixtures/subscription.rb +4 -0
- data/vendor/gems/simple_taggable/test/fixtures/subscriptions.yml +3 -0
- data/vendor/gems/simple_taggable/test/fixtures/taggings.yml +112 -0
- data/vendor/gems/simple_taggable/test/fixtures/tags.yml +14 -0
- data/vendor/gems/simple_taggable/test/fixtures/user.rb +6 -0
- data/vendor/gems/simple_taggable/test/fixtures/users.yml +5 -0
- data/vendor/gems/simple_taggable/test/log/simple_taggable.log +1614 -0
- data/vendor/gems/simple_taggable/test/simple_taggable_test.rb +226 -0
- data/vendor/gems/simple_taggable/test/tag_list_test.rb +105 -0
- data/vendor/gems/simple_taggable/test/test_helper.rb +80 -0
- data/vendor/gems/table_builder/.gitignore +17 -0
- data/vendor/gems/table_builder/Gemfile +4 -0
- data/vendor/gems/table_builder/LICENSE +22 -0
- data/vendor/gems/table_builder/README.md +29 -0
- data/vendor/gems/table_builder/Rakefile +2 -0
- data/vendor/gems/table_builder/lib/table_builder.rb +27 -0
- data/vendor/gems/table_builder/lib/table_builder/body.rb +28 -0
- data/vendor/gems/table_builder/lib/table_builder/cell.rb +21 -0
- data/vendor/gems/table_builder/lib/table_builder/column.rb +26 -0
- data/vendor/gems/table_builder/lib/table_builder/foot.rb +6 -0
- data/vendor/gems/table_builder/lib/table_builder/head.rb +16 -0
- data/vendor/gems/table_builder/lib/table_builder/row.rb +40 -0
- data/vendor/gems/table_builder/lib/table_builder/rows.rb +26 -0
- data/vendor/gems/table_builder/lib/table_builder/table.rb +75 -0
- data/vendor/gems/table_builder/lib/table_builder/tag.rb +58 -0
- data/vendor/gems/table_builder/lib/table_builder/version.rb +3 -0
- data/vendor/gems/table_builder/table_builder.gemspec +17 -0
- data/vendor/gems/table_builder/test/fixtures/templates/table_all.html.erb +20 -0
- data/vendor/gems/table_builder/test/fixtures/templates/table_auto_body.html.erb +3 -0
- data/vendor/gems/table_builder/test/fixtures/templates/table_auto_columns.html.erb +1 -0
- data/vendor/gems/table_builder/test/fixtures/templates/table_simple.html.erb +7 -0
- data/vendor/gems/table_builder/test/table_builder/table_test.rb +230 -0
- data/vendor/gems/table_builder/test/test_helper.rb +49 -0
- data/vendor/gems/tags/.gitignore +17 -0
- data/vendor/gems/tags/Gemfile +4 -0
- data/vendor/gems/tags/LICENSE +22 -0
- data/vendor/gems/tags/README.md +29 -0
- data/vendor/gems/tags/Rakefile +2 -0
- data/vendor/gems/tags/lib/breadcrumbs.rb +13 -0
- data/vendor/gems/tags/lib/menu.rb +179 -0
- data/vendor/gems/tags/lib/menu/builder.rb +74 -0
- data/vendor/gems/tags/lib/tags.rb +7 -0
- data/vendor/gems/tags/lib/tags/tag.rb +125 -0
- data/vendor/gems/tags/lib/tags/version.rb +3 -0
- data/vendor/gems/tags/tags.gemspec +17 -0
- data/vendor/gems/tags/test/tags/menu_test.rb +173 -0
- data/vendor/gems/tags/test/tags/tag_test.rb +13 -0
- data/vendor/gems/tags/test/test_helper.rb +18 -0
- data/vendor/gems/xss_terminate/.gitignore +17 -0
- data/vendor/gems/xss_terminate/Gemfile +4 -0
- data/vendor/gems/xss_terminate/LICENSE +22 -0
- data/vendor/gems/xss_terminate/MIT-LICENSE +20 -0
- data/vendor/gems/xss_terminate/README +94 -0
- data/vendor/gems/xss_terminate/README.md +29 -0
- data/vendor/gems/xss_terminate/Rakefile +23 -0
- data/vendor/gems/xss_terminate/lib/html5lib_sanitize.rb +2453 -0
- data/vendor/gems/xss_terminate/lib/rails_sanitize.rb +8 -0
- data/vendor/gems/xss_terminate/lib/xss_terminate.rb +141 -0
- data/vendor/gems/xss_terminate/lib/xss_terminate/version.rb +3 -0
- data/vendor/gems/xss_terminate/tasks/xss_terminate_tasks.rake +7 -0
- data/vendor/gems/xss_terminate/test/models/comment.rb +5 -0
- data/vendor/gems/xss_terminate/test/models/entry.rb +7 -0
- data/vendor/gems/xss_terminate/test/models/message.rb +3 -0
- data/vendor/gems/xss_terminate/test/models/person.rb +5 -0
- data/vendor/gems/xss_terminate/test/models/review.rb +5 -0
- data/vendor/gems/xss_terminate/test/schema.rb +34 -0
- data/vendor/gems/xss_terminate/test/setup_test.rb +16 -0
- data/vendor/gems/xss_terminate/test/xss_terminate_test.rb +50 -0
- data/vendor/gems/xss_terminate/xss_terminate.gemspec +17 -0
- metadata +744 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'abstract_unit')
|
|
2
|
+
|
|
3
|
+
class FilteredColumnTest < Test::Unit::TestCase
|
|
4
|
+
{
|
|
5
|
+
:textile => { :input => '*foo*', :output => '<p><strong>foo</strong></p>' },
|
|
6
|
+
:markdown => { :input => "# bar\n\nfoo", :output => "<h1>bar</h1>\n\n<p>foo</p>" },
|
|
7
|
+
:smartypants => { :input => "\"abc\" `<def ghi=\"jkl\">`\n\n <mno pqr=\"stu\">...</mno>",
|
|
8
|
+
:output => "<p>“abc” <code><def ghi=\"jkl\"></code></p>\n\n<pre><code><mno pqr=\"stu\">...</mno>\n</code></pre>" },
|
|
9
|
+
}.each do |filter_name, values|
|
|
10
|
+
define_method "test_should_filter_with_#{filter_name}" do
|
|
11
|
+
assert_equal values[:output], FilteredColumn::Processor.new("#{filter_name}_filter", values[:input]).filter
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
define_method "test_should_filter_model_attribute_with_#{filter_name}" do
|
|
15
|
+
assert_filters_called_on "#{filter_name}_filter".to_sym do
|
|
16
|
+
a = Article.create :body => values[:input], :filter => "#{filter_name}_filter"
|
|
17
|
+
assert_equal values[:output], a.body_html
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def test_should_retrieve_filter
|
|
23
|
+
assert_equal FilteredColumn::Filters::TextileFilter, FilteredColumn.filters[:textile_filter]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def test_should_use_default_filter_names
|
|
27
|
+
assert_equal 'Textile', FilteredColumn::Filters::TextileFilter.filter_name
|
|
28
|
+
assert_equal 'Markdown', FilteredColumn::Filters::MarkdownFilter.filter_name
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def test_should_allow_filter_name_customization
|
|
32
|
+
assert_equal 'Markdown with Smarty Pants', FilteredColumn::Filters::SmartypantsFilter.filter_name
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def test_should_use_default_filter_keys
|
|
36
|
+
assert_equal :textile_filter, FilteredColumn::Filters::TextileFilter.filter_key
|
|
37
|
+
assert_equal :markdown_filter, FilteredColumn::Filters::MarkdownFilter.filter_key
|
|
38
|
+
assert_equal :smartypants_filter, FilteredColumn::Filters::SmartypantsFilter.filter_key
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def test_should_call_no_filters_with_no_data
|
|
42
|
+
assert_no_filters_called_on(Article) { Article.new }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def test_should_escape_textile_filter
|
|
46
|
+
assert_equal '<notextile>foo</notextile>', FilteredColumn::Filters::TextileFilter.escape('foo')
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def test_should_parse_content_with_html_tokenizer
|
|
50
|
+
article = Article.create :body => '*foo*', :filter => "textile_filter"
|
|
51
|
+
assert_kind_of HTML::Document, article.body_doc
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'abstract_unit')
|
|
2
|
+
|
|
3
|
+
class MacroFilterTest < Test::Unit::TestCase
|
|
4
|
+
def test_should_retrieve_macro
|
|
5
|
+
assert_equal SampleMacro, FilteredColumn.macros[:sample_macro]
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def test_sample_macro
|
|
9
|
+
assert_equal %(foo: - flip: - text: test), process_macros("<macro:sample>test</macro:sample>")
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def test_sample_macro_with_attributes
|
|
13
|
+
assert_equal %(foo: foo - flip: bar - text: test), process_macros(%(<macro:sample foo="foo" flip="bar">test</macro:sample>))
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def test_sample_macro_with_underscored_attributes
|
|
17
|
+
assert_equal %(foo: foo - flip: bar - text: test), process_macros(%(<macro:sample foo_bar="foo" flip="bar">test</macro:sample>))
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def test_should_escape_macros_with_textile
|
|
21
|
+
assert_equal %(foo: - flip: - text: <tt>test</tt>), process_filter(:textile_filter, "<macro:sample><tt>test</tt></macro:sample>")
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2012 Micah Geisel
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2008 Sven Fuchs
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
## Has Counter
|
|
2
|
+
|
|
3
|
+
Allows to cache the number of records for a `has_many` association.
|
|
4
|
+
|
|
5
|
+
Yes, this is the same thing you can do by setting the `:counter_cache` option
|
|
6
|
+
on the corresponding `belongs_to` association.
|
|
7
|
+
|
|
8
|
+
The reason for reinventing the `counter_cache` wheel here is that
|
|
9
|
+
`counter_cache` is a bit inflexible. We need to "hardcode" the counter_cache
|
|
10
|
+
column and thereby clutter the schema. This can especially get annoying in
|
|
11
|
+
combo with STI, when - e.g. one subclass needs some `counter_caches` that are
|
|
12
|
+
specific to this subclass only.
|
|
13
|
+
|
|
14
|
+
Instead, with `has_counter`, counters can be separated into an external table
|
|
15
|
+
with generic column names.
|
|
16
|
+
|
|
17
|
+
The ActiveRecord `counter_cache` mechanism also requires to put the
|
|
18
|
+
`:counter_cache` directive on the `belongs_to` association of the counted class,
|
|
19
|
+
which adds some tight coupleing that we might want to avoid.
|
|
20
|
+
|
|
21
|
+
Instead, with `has_counter`, we can observe the counted class and update our
|
|
22
|
+
counters "from the outside", so the counted class does not need to know about
|
|
23
|
+
the fact that somebody else keeps a counter on it.
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
class User
|
|
28
|
+
has_counter :posts
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
This will add a `has_one :post_counter` association to the User model as well
|
|
32
|
+
as the appropriate callbacks for creating the initial counter object when a
|
|
33
|
+
User is created and in/decrementing the counter when a Post is created or
|
|
34
|
+
destroyed.
|
|
35
|
+
|
|
36
|
+
For convenience it also adds a `posts_count` method to the User model that you
|
|
37
|
+
should use to read the actual numeric count value.
|
|
38
|
+
|
|
39
|
+
In case you need that you can use the following methods to manually
|
|
40
|
+
in/decrement or set the counter value:
|
|
41
|
+
|
|
42
|
+
user.posts_counter.increment! # increments and saves the counter
|
|
43
|
+
user.posts_counter.decrement! # decrement and saves the counter
|
|
44
|
+
user.posts_counter.set(5) # sets the counter to 5 and saves it
|
|
45
|
+
|
|
46
|
+
## Limitations
|
|
47
|
+
|
|
48
|
+
There are quite some. The above example expects that there is the following
|
|
49
|
+
association on the Posts model:
|
|
50
|
+
|
|
51
|
+
class Post
|
|
52
|
+
belongs_to :user
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
`User.has_counter :posts` also expects that a Post model exists and that this
|
|
56
|
+
is the one you want to count. At this point you can **not** count arbitrary
|
|
57
|
+
associations like:
|
|
58
|
+
|
|
59
|
+
class Post
|
|
60
|
+
has_counter :approved_comments # with special conditions/callbacks
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# HasCounter
|
|
2
|
+
|
|
3
|
+
TODO: Write a gem description
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Add this line to your application's Gemfile:
|
|
8
|
+
|
|
9
|
+
gem 'has_counter'
|
|
10
|
+
|
|
11
|
+
And then execute:
|
|
12
|
+
|
|
13
|
+
$ bundle
|
|
14
|
+
|
|
15
|
+
Or install it yourself as:
|
|
16
|
+
|
|
17
|
+
$ gem install has_counter
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
TODO: Write usage instructions here
|
|
22
|
+
|
|
23
|
+
## Contributing
|
|
24
|
+
|
|
25
|
+
1. Fork it
|
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
27
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
|
29
|
+
5. Create new Pull Request
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
class CreateCountersTable < ActiveRecord::Migration
|
|
2
|
+
def self.up
|
|
3
|
+
create_table :counters, :force => true do |t|
|
|
4
|
+
t.references :owner, :polymorphic => true
|
|
5
|
+
t.string :name, :limit => 25
|
|
6
|
+
t.integer :count, :default => 0
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.down
|
|
11
|
+
drop_table :counters
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
require File.expand_path('../lib/has_counter/version', __FILE__)
|
|
3
|
+
|
|
4
|
+
Gem::Specification.new do |gem|
|
|
5
|
+
gem.authors = ["Micah Geisel"]
|
|
6
|
+
gem.email = ["micah@botandrose.com"]
|
|
7
|
+
gem.description = %q{TODO: Write a gem description}
|
|
8
|
+
gem.summary = %q{TODO: Write a gem summary}
|
|
9
|
+
gem.homepage = ""
|
|
10
|
+
|
|
11
|
+
gem.files = `git ls-files`.split($\)
|
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
|
14
|
+
gem.name = "has_counter"
|
|
15
|
+
gem.require_paths = ["lib"]
|
|
16
|
+
gem.version = HasCounter::VERSION
|
|
17
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
module ActiveRecord
|
|
2
|
+
module HasCounter
|
|
3
|
+
class << self
|
|
4
|
+
def included(base)
|
|
5
|
+
base.extend ActMacro
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
module ActMacro
|
|
10
|
+
def has_counter(*names)
|
|
11
|
+
options = names.extract_options!
|
|
12
|
+
callbacks = options[:callbacks] || { :after_create => :increment!, :after_destroy => :decrement! }
|
|
13
|
+
|
|
14
|
+
class_attribute :"update_counters"
|
|
15
|
+
self.update_counters ||= {}
|
|
16
|
+
|
|
17
|
+
names.each do |name|
|
|
18
|
+
counter_name = :"#{name}_counter"
|
|
19
|
+
owner_name = options[:as] || self.name.demodulize.underscore
|
|
20
|
+
class_name = options[:class_name] || name
|
|
21
|
+
|
|
22
|
+
define_method :"#{name}_count" do
|
|
23
|
+
send(counter_name).count
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
has_one counter_name, -> { where(name: name) },
|
|
27
|
+
as: :owner,
|
|
28
|
+
class_name: "Counter",
|
|
29
|
+
dependent: :delete
|
|
30
|
+
|
|
31
|
+
# create the counter lazily upon first access
|
|
32
|
+
class_eval <<-code, __FILE__, __LINE__
|
|
33
|
+
def #{counter_name}_with_lazy_creation(force_reload = false)
|
|
34
|
+
result = #{counter_name}_without_lazy_creation(force_reload)
|
|
35
|
+
if result.nil?
|
|
36
|
+
Counter.create!(:owner => self, :name => #{name.to_s.inspect})
|
|
37
|
+
result = #{counter_name}_without_lazy_creation(true)
|
|
38
|
+
end
|
|
39
|
+
result
|
|
40
|
+
end
|
|
41
|
+
alias_method_chain counter_name, :lazy_creation
|
|
42
|
+
code
|
|
43
|
+
|
|
44
|
+
# Wire up the counted class so that it updates our counter, basically
|
|
45
|
+
# an anonymous callback/observer pattern
|
|
46
|
+
target = class_name.to_s.classify.constantize
|
|
47
|
+
callbacks.keys.each do |callback|
|
|
48
|
+
target.send callback do |record|
|
|
49
|
+
owner = record.send(owner_name) if record.respond_to?(owner_name)
|
|
50
|
+
# do not update the counter when counter's owner (e.g. article) is not frozen (deleted)
|
|
51
|
+
if self === owner && !owner.frozen? && record.class == target
|
|
52
|
+
method = callbacks[callback]
|
|
53
|
+
method = method.call(record) if Proc === method
|
|
54
|
+
counter = owner.send(counter_name) if method
|
|
55
|
+
counter.send method if counter && method
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
class Counter < ActiveRecord::Base
|
|
2
|
+
belongs_to :owner, :polymorphic => true
|
|
3
|
+
|
|
4
|
+
def increment!
|
|
5
|
+
set count + 1
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def increment_by!(value)
|
|
9
|
+
set count + value
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def decrement!
|
|
13
|
+
set count - 1
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def decrement_by!(value)
|
|
17
|
+
set count - value
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def set(value)
|
|
21
|
+
update_attributes! :count => value
|
|
22
|
+
end
|
|
23
|
+
end
|
|
File without changes
|
|
Binary file
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/spec_helper.rb")
|
|
2
|
+
|
|
3
|
+
describe "has_counter:", "using default after_create and after_destroy callbacks" do
|
|
4
|
+
before :each do
|
|
5
|
+
Counter.delete_all
|
|
6
|
+
CounterSpec::Content.delete_all
|
|
7
|
+
CounterSpec::Comment.delete_all
|
|
8
|
+
|
|
9
|
+
@content = CounterSpec::Content.create! :title => 'first content'
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "instantiates a counter" do
|
|
13
|
+
@content.comments.create! :text => 'first comment'
|
|
14
|
+
@content.comments_counter.should_not be_nil
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "increments the counter on creation" do
|
|
18
|
+
@content.comments.create! :text => 'first comment'
|
|
19
|
+
@content.comments_count.should == 1
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "decrements the counter on deletion" do
|
|
23
|
+
@comment = @content.comments.create! :text => 'first comment'
|
|
24
|
+
@comment.destroy
|
|
25
|
+
@content.comments_count.should == 0
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe "has_counter:", "using a method name as after_create and after_destroy callbacks" do
|
|
30
|
+
before :each do
|
|
31
|
+
Counter.delete_all
|
|
32
|
+
CounterSpec::Content.delete_all
|
|
33
|
+
CounterSpec::Comment.delete_all
|
|
34
|
+
|
|
35
|
+
@content = CounterSpec::Content.create! :title => 'first content'
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "instantiates a counter" do
|
|
39
|
+
@content.comments.create! :text => 'first comment'
|
|
40
|
+
@content.approved_comments_counter.should_not be_nil
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "increments the counter on creation" do
|
|
44
|
+
@content.comments.create! :text => 'first comment', :approved => 1
|
|
45
|
+
@content.approved_comments_count.should == 1
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "decrements the counter on deletion" do
|
|
49
|
+
@comment = @content.comments.create! :text => 'first comment', :approved => 1
|
|
50
|
+
@content.approved_comments_count.should == 1
|
|
51
|
+
@comment.destroy
|
|
52
|
+
@content.reload
|
|
53
|
+
@content.approved_comments_count.should == 0
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
$LOAD_PATH << File.dirname(__FILE__) + '/../lib/'
|
|
2
|
+
|
|
3
|
+
ENV["RAILS_ENV"] = "test"
|
|
4
|
+
|
|
5
|
+
require 'rubygems'
|
|
6
|
+
require 'active_record'
|
|
7
|
+
|
|
8
|
+
ActiveRecord::Base.class_eval do
|
|
9
|
+
class << self
|
|
10
|
+
# no peeping toms (aka observers) wanted here
|
|
11
|
+
alias_method :dont_instantiate_observers, :instantiate_observers
|
|
12
|
+
def instantiate_observers; end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
require File.expand_path(File.dirname(__FILE__) + "/../../../../config/environment")
|
|
17
|
+
require 'spec'
|
|
18
|
+
require 'spec/rails'
|
|
19
|
+
|
|
20
|
+
config = {'adapter' => 'sqlite3', 'dbfile' => File.dirname(__FILE__) + '/has_counter.sqlite3.db'}
|
|
21
|
+
ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + '/has_counter.spec.log')
|
|
22
|
+
ActiveRecord::Base.establish_connection(config)
|
|
23
|
+
|
|
24
|
+
require 'counter'
|
|
25
|
+
unless Counter.table_exists?
|
|
26
|
+
ActiveRecord::Migration.verbose = false
|
|
27
|
+
ActiveRecord::Schema.define(:version => 1) do
|
|
28
|
+
create_table :counters, :force => true do |t|
|
|
29
|
+
t.references :owner, :polymorphic => true
|
|
30
|
+
t.string :name, :limit => 25
|
|
31
|
+
t.integer :count, :default => 0
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
module CounterSpec
|
|
37
|
+
class Comment < ActiveRecord::Base
|
|
38
|
+
self.table_name = 'comments'
|
|
39
|
+
|
|
40
|
+
belongs_to :content
|
|
41
|
+
after_save :update_commentable
|
|
42
|
+
after_destroy :update_commentable
|
|
43
|
+
|
|
44
|
+
unless table_exists?
|
|
45
|
+
ActiveRecord::Migration.verbose = false
|
|
46
|
+
ActiveRecord::Schema.define(:version => 1) do
|
|
47
|
+
create_table :comments, :force => true do |t|
|
|
48
|
+
t.references :content
|
|
49
|
+
t.text :text
|
|
50
|
+
t.integer :approved
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def unapproved?
|
|
56
|
+
!approved?
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def just_approved?
|
|
60
|
+
approved? && approved_changed?
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def just_unapproved?
|
|
64
|
+
!approved? && approved_changed?
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def update_commentable
|
|
68
|
+
content.after_comment_update(self)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
class Content < ActiveRecord::Base
|
|
73
|
+
self.table_name = 'contents'
|
|
74
|
+
|
|
75
|
+
has_many :comments
|
|
76
|
+
|
|
77
|
+
has_counter :comments,
|
|
78
|
+
:class_name => 'CounterSpec::Comment'
|
|
79
|
+
|
|
80
|
+
has_counter :approved_comments,
|
|
81
|
+
:class_name => 'CounterSpec::Comment',
|
|
82
|
+
:after_create => false,
|
|
83
|
+
:after_destroy => false
|
|
84
|
+
# :after_destroy => lambda{|record|
|
|
85
|
+
# :decrement! if record.approved?
|
|
86
|
+
# },
|
|
87
|
+
# :after_save => lambda{|record|
|
|
88
|
+
# record.just_approved? && :increment! or
|
|
89
|
+
# record.just_unapproved? && :decrement!
|
|
90
|
+
# }
|
|
91
|
+
|
|
92
|
+
def after_comment_update(comment)
|
|
93
|
+
method = if comment.frozen? && comment.approved?
|
|
94
|
+
:decrement!
|
|
95
|
+
elsif comment.just_approved?
|
|
96
|
+
:increment!
|
|
97
|
+
elsif comment.just_unapproved?
|
|
98
|
+
:decrement!
|
|
99
|
+
end
|
|
100
|
+
approved_comments_counter.send method if method
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
unless table_exists?
|
|
104
|
+
ActiveRecord::Migration.verbose = false
|
|
105
|
+
ActiveRecord::Schema.define(:version => 1) do
|
|
106
|
+
create_table :contents, :force => true do |t|
|
|
107
|
+
t.string :title, :limit => 50
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
|