serum-rails 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (340) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +6 -0
  3. data/.rspec +3 -0
  4. data/Gemfile +3 -0
  5. data/Gemfile.lock +42 -0
  6. data/LICENSE +22 -0
  7. data/README.md +40 -0
  8. data/bin/serum-rails +13 -0
  9. data/lib/serum/rails/app.rb +50 -0
  10. data/lib/serum/rails/code_scanner.rb +49 -0
  11. data/lib/serum/rails/metrics.rb +118 -0
  12. data/lib/serum/rails/type_selection.rb +31 -0
  13. data/lib/serum/rails/version.rb +7 -0
  14. data/lib/serum-rails.rb +5 -0
  15. data/serum-rails.gemspec +23 -0
  16. data/spec/serum/rails/metrics_spec.rb +87 -0
  17. data/spec/spec_helper.rb +80 -0
  18. data/spec/test_app/Capfile +4 -0
  19. data/spec/test_app/Gemfile +54 -0
  20. data/spec/test_app/Gemfile.lock +163 -0
  21. data/spec/test_app/Rakefile +11 -0
  22. data/spec/test_app/app/controllers/admin/categories_controller.rb +17 -0
  23. data/spec/test_app/app/controllers/admin/users_controller.rb +30 -0
  24. data/spec/test_app/app/controllers/application_controller/i18n_trait.rb +24 -0
  25. data/spec/test_app/app/controllers/application_controller/navigation_trait.rb +19 -0
  26. data/spec/test_app/app/controllers/application_controller/security_trait/disabled_clearance_accounts_trait.rb +41 -0
  27. data/spec/test_app/app/controllers/application_controller/security_trait.rb +65 -0
  28. data/spec/test_app/app/controllers/application_controller.rb +13 -0
  29. data/spec/test_app/app/controllers/conferences_controller.rb +67 -0
  30. data/spec/test_app/app/controllers/friendship_requests_controller.rb +31 -0
  31. data/spec/test_app/app/controllers/invitations_controller.rb +39 -0
  32. data/spec/test_app/app/controllers/members_controller.rb +21 -0
  33. data/spec/test_app/app/controllers/passwords_controller.rb +33 -0
  34. data/spec/test_app/app/controllers/sessions_controller.rb +17 -0
  35. data/spec/test_app/app/controllers/shared/boring_controller_trait/deletable_trait.rb +23 -0
  36. data/spec/test_app/app/controllers/shared/boring_controller_trait/flash_trait.rb +23 -0
  37. data/spec/test_app/app/controllers/shared/boring_controller_trait/helpers_trait.rb +35 -0
  38. data/spec/test_app/app/controllers/shared/boring_controller_trait/index_trait.rb +39 -0
  39. data/spec/test_app/app/controllers/shared/boring_controller_trait/log_changes_trait.rb +18 -0
  40. data/spec/test_app/app/controllers/shared/boring_controller_trait.rb +16 -0
  41. data/spec/test_app/app/controllers/users_controller.rb +49 -0
  42. data/spec/test_app/app/controllers/ws/api_controller/formatters_trait.rb +91 -0
  43. data/spec/test_app/app/controllers/ws/api_controller/parsers_trait.rb +59 -0
  44. data/spec/test_app/app/controllers/ws/api_controller.rb +70 -0
  45. data/spec/test_app/app/controllers/ws/attendees_controller.rb +43 -0
  46. data/spec/test_app/app/controllers/ws/categories_controller.rb +30 -0
  47. data/spec/test_app/app/controllers/ws/conferences_controller.rb +62 -0
  48. data/spec/test_app/app/controllers/ws/contacts_controller.rb +41 -0
  49. data/spec/test_app/app/controllers/ws/factory_controller.rb +45 -0
  50. data/spec/test_app/app/controllers/ws/members_controller.rb +34 -0
  51. data/spec/test_app/app/controllers/ws/series_controller.rb +19 -0
  52. data/spec/test_app/app/controllers/ws/tests_controller.rb +23 -0
  53. data/spec/test_app/app/helpers/application_helper.rb +180 -0
  54. data/spec/test_app/app/helpers/mail_helper.rb +9 -0
  55. data/spec/test_app/app/helpers/tags_helper.rb +16 -0
  56. data/spec/test_app/app/helpers/user_helper.rb +23 -0
  57. data/spec/test_app/app/models/attendance.rb +11 -0
  58. data/spec/test_app/app/models/category/ancestry_trait.rb +23 -0
  59. data/spec/test_app/app/models/category.rb +25 -0
  60. data/spec/test_app/app/models/conference/attendance_trait.rb +23 -0
  61. data/spec/test_app/app/models/conference/categories_trait.rb +26 -0
  62. data/spec/test_app/app/models/conference/icalendar_trait.rb +36 -0
  63. data/spec/test_app/app/models/conference/search_trait.rb +44 -0
  64. data/spec/test_app/app/models/conference.rb +24 -0
  65. data/spec/test_app/app/models/conference_category.rb +6 -0
  66. data/spec/test_app/app/models/conference_search.rb +51 -0
  67. data/spec/test_app/app/models/error.rb +25 -0
  68. data/spec/test_app/app/models/friendship.rb +14 -0
  69. data/spec/test_app/app/models/friendship_request.rb +19 -0
  70. data/spec/test_app/app/models/invitation.rb +38 -0
  71. data/spec/test_app/app/models/member_search.rb +18 -0
  72. data/spec/test_app/app/models/navigation.rb +38 -0
  73. data/spec/test_app/app/models/patterns.rb +14 -0
  74. data/spec/test_app/app/models/permissions.rb +106 -0
  75. data/spec/test_app/app/models/shared/afterlife_trait.rb +18 -0
  76. data/spec/test_app/app/models/shared/choice_trait.rb +37 -0
  77. data/spec/test_app/app/models/shared/deletable_trait.rb +8 -0
  78. data/spec/test_app/app/models/shared/flag_trait.rb +30 -0
  79. data/spec/test_app/app/models/shared/indestructible_trait.rb +19 -0
  80. data/spec/test_app/app/models/shared/list_field_trait.rb +70 -0
  81. data/spec/test_app/app/models/shared/person_name_trait.rb +25 -0
  82. data/spec/test_app/app/models/shared/searchable_trait.rb +71 -0
  83. data/spec/test_app/app/models/shared/sortable_trait.rb +24 -0
  84. data/spec/test_app/app/models/user/authentication_trait.rb +33 -0
  85. data/spec/test_app/app/models/user/authorization_trait.rb +17 -0
  86. data/spec/test_app/app/models/user/friends_trait.rb +42 -0
  87. data/spec/test_app/app/models/user/search_trait.rb +43 -0
  88. data/spec/test_app/app/models/user.rb +61 -0
  89. data/spec/test_app/app/models/util.rb +19 -0
  90. data/spec/test_app/app/views/admin/categories/_form.html.haml +18 -0
  91. data/spec/test_app/app/views/admin/categories/_list.html.haml +17 -0
  92. data/spec/test_app/app/views/admin/categories/edit.html.haml +6 -0
  93. data/spec/test_app/app/views/admin/categories/index.html.haml +6 -0
  94. data/spec/test_app/app/views/admin/categories/new.html.haml +6 -0
  95. data/spec/test_app/app/views/admin/categories/show.html.haml +27 -0
  96. data/spec/test_app/app/views/admin/users/_form.html.haml +49 -0
  97. data/spec/test_app/app/views/admin/users/_head.html.haml +5 -0
  98. data/spec/test_app/app/views/admin/users/_list.html.haml +20 -0
  99. data/spec/test_app/app/views/admin/users/_search.html.haml +9 -0
  100. data/spec/test_app/app/views/admin/users/deleted.html.haml +5 -0
  101. data/spec/test_app/app/views/admin/users/edit.html.haml +5 -0
  102. data/spec/test_app/app/views/admin/users/index.html.haml +7 -0
  103. data/spec/test_app/app/views/admin/users/new.html.haml +6 -0
  104. data/spec/test_app/app/views/clearance_mailer/change_password.erb +9 -0
  105. data/spec/test_app/app/views/conferences/_categories_list.html.haml +8 -0
  106. data/spec/test_app/app/views/conferences/_form.html.haml +32 -0
  107. data/spec/test_app/app/views/conferences/_head.html.haml +4 -0
  108. data/spec/test_app/app/views/conferences/_list.html.haml +22 -0
  109. data/spec/test_app/app/views/conferences/_search.html.haml +24 -0
  110. data/spec/test_app/app/views/conferences/edit.html.haml +8 -0
  111. data/spec/test_app/app/views/conferences/index.html.haml +22 -0
  112. data/spec/test_app/app/views/conferences/new.html.haml +9 -0
  113. data/spec/test_app/app/views/conferences/search.html.haml +7 -0
  114. data/spec/test_app/app/views/conferences/show.html.haml +78 -0
  115. data/spec/test_app/app/views/invitations/index.html.haml +26 -0
  116. data/spec/test_app/app/views/invitations/new.html.haml +22 -0
  117. data/spec/test_app/app/views/layouts/_flashes.html.haml +13 -0
  118. data/spec/test_app/app/views/layouts/_javascript_requirement.html.haml +8 -0
  119. data/spec/test_app/app/views/layouts/_javascripts.html.haml +4 -0
  120. data/spec/test_app/app/views/layouts/_notifications.html.haml +11 -0
  121. data/spec/test_app/app/views/layouts/_session_navigation.html.haml +12 -0
  122. data/spec/test_app/app/views/layouts/_stylesheets.html.haml +6 -0
  123. data/spec/test_app/app/views/layouts/screen.html.haml +30 -0
  124. data/spec/test_app/app/views/members/index.html.haml +40 -0
  125. data/spec/test_app/app/views/passwords/edit.html.haml +21 -0
  126. data/spec/test_app/app/views/passwords/new.html.haml +14 -0
  127. data/spec/test_app/app/views/sessions/new.html.haml +19 -0
  128. data/spec/test_app/app/views/users/_form.html.haml +45 -0
  129. data/spec/test_app/app/views/users/_head.html.haml +3 -0
  130. data/spec/test_app/app/views/users/edit.html.haml +5 -0
  131. data/spec/test_app/app/views/users/new.html.haml +6 -0
  132. data/spec/test_app/app/views/users/show.html.haml +49 -0
  133. data/spec/test_app/assets/data.json +981 -0
  134. data/spec/test_app/config/boot.rb +125 -0
  135. data/spec/test_app/config/cucumber.yml +8 -0
  136. data/spec/test_app/config/database.sample.yml +24 -0
  137. data/spec/test_app/config/deploy/production.rb +9 -0
  138. data/spec/test_app/config/deploy.rb +100 -0
  139. data/spec/test_app/config/environment.rb +27 -0
  140. data/spec/test_app/config/environments/cucumber.rb +28 -0
  141. data/spec/test_app/config/environments/development.rb +22 -0
  142. data/spec/test_app/config/environments/production.rb +35 -0
  143. data/spec/test_app/config/environments/test.rb +30 -0
  144. data/spec/test_app/config/initializers/backtrace_silencers.rb +7 -0
  145. data/spec/test_app/config/initializers/clearance.rb +5 -0
  146. data/spec/test_app/config/initializers/collect_hash.rb +23 -0
  147. data/spec/test_app/config/initializers/collection_path_with_params.rb +18 -0
  148. data/spec/test_app/config/initializers/cookie_verification_secret.rb +10 -0
  149. data/spec/test_app/config/initializers/form_builder.rb +166 -0
  150. data/spec/test_app/config/initializers/inflections.rb +10 -0
  151. data/spec/test_app/config/initializers/invert_ordered_hash.rb +12 -0
  152. data/spec/test_app/config/initializers/localize_textfield_input_for_numbers.rb +30 -0
  153. data/spec/test_app/config/initializers/mime_types.rb +7 -0
  154. data/spec/test_app/config/initializers/new_rails_defaults.rb +21 -0
  155. data/spec/test_app/config/initializers/preload_associations.rb +7 -0
  156. data/spec/test_app/config/initializers/query_diet.rb +6 -0
  157. data/spec/test_app/config/initializers/saner_field_with_errors.rb +5 -0
  158. data/spec/test_app/config/initializers/session_store.rb +18 -0
  159. data/spec/test_app/config/locales/en.yml +231 -0
  160. data/spec/test_app/config/preinitializer.rb +22 -0
  161. data/spec/test_app/config/routes.rb +47 -0
  162. data/spec/test_app/db/migrate/20110114164517_initial_tables.rb +52 -0
  163. data/spec/test_app/db/migrate/20110118090858_add_profile_fields_to_user.rb +15 -0
  164. data/spec/test_app/db/migrate/20110118092741_create_conference.rb +20 -0
  165. data/spec/test_app/db/migrate/20110118093503_create_category.rb +17 -0
  166. data/spec/test_app/db/migrate/20110118104438_create_conference_category.rb +16 -0
  167. data/spec/test_app/db/migrate/20110118105959_create_attendance.rb +17 -0
  168. data/spec/test_app/db/migrate/20110118122324_create_friendship_requests.rb +15 -0
  169. data/spec/test_app/db/migrate/20110118162436_create_invitation.rb +16 -0
  170. data/spec/test_app/db/migrate/20110118170347_create_friendships.rb +15 -0
  171. data/spec/test_app/db/migrate/20110118193528_add_timestamps_to_conference.rb +12 -0
  172. data/spec/test_app/db/migrate/20110119075012_set_unique_index_on_username_for_user.rb +11 -0
  173. data/spec/test_app/db/migrate/20110119093458_remove_first_and_last_name_from_user.rb +12 -0
  174. data/spec/test_app/db/migrate/20110119110857_add_missing_indexes.rb +23 -0
  175. data/spec/test_app/db/migrate/20110119115751_add_uniqueness_of_name_to_category.rb +9 -0
  176. data/spec/test_app/db/seeds.rb +5 -0
  177. data/spec/test_app/lib/scripts/create_many_users_sql.rb +14 -0
  178. data/spec/test_app/lib/tasks/cucumber.rake +53 -0
  179. data/spec/test_app/lib/tasks/pending_migrations.rake +24 -0
  180. data/spec/test_app/lib/tasks/rcov.rake +42 -0
  181. data/spec/test_app/lib/tasks/rspec.rake +144 -0
  182. data/spec/test_app/public/404.html +30 -0
  183. data/spec/test_app/public/422.html +30 -0
  184. data/spec/test_app/public/500.html +30 -0
  185. data/spec/test_app/public/favicon.ico +0 -0
  186. data/spec/test_app/public/images/ajax-loader.gif +0 -0
  187. data/spec/test_app/public/images/icons/balloon-quotation.png +0 -0
  188. data/spec/test_app/public/images/icons/balloon-sound.png +0 -0
  189. data/spec/test_app/public/images/icons/balloon.png +0 -0
  190. data/spec/test_app/public/images/icons/bell.png +0 -0
  191. data/spec/test_app/public/images/icons/bin.png +0 -0
  192. data/spec/test_app/public/images/icons/bookmark.png +0 -0
  193. data/spec/test_app/public/images/icons/cake.png +0 -0
  194. data/spec/test_app/public/images/icons/calendar-blue.png +0 -0
  195. data/spec/test_app/public/images/icons/calendar-month.png +0 -0
  196. data/spec/test_app/public/images/icons/calendar-month_light.png +0 -0
  197. data/spec/test_app/public/images/icons/calendar-select.png +0 -0
  198. data/spec/test_app/public/images/icons/card-address.png +0 -0
  199. data/spec/test_app/public/images/icons/cards-address.png +0 -0
  200. data/spec/test_app/public/images/icons/cross-script.png +0 -0
  201. data/spec/test_app/public/images/icons/cross-small.png +0 -0
  202. data/spec/test_app/public/images/icons/cross.png +0 -0
  203. data/spec/test_app/public/images/icons/crown-silver.png +0 -0
  204. data/spec/test_app/public/images/icons/crown.png +0 -0
  205. data/spec/test_app/public/images/icons/dashboard.png +0 -0
  206. data/spec/test_app/public/images/icons/document-list.png +0 -0
  207. data/spec/test_app/public/images/icons/document-node.png +0 -0
  208. data/spec/test_app/public/images/icons/document-number.png +0 -0
  209. data/spec/test_app/public/images/icons/document-stamp.png +0 -0
  210. data/spec/test_app/public/images/icons/document-task.png +0 -0
  211. data/spec/test_app/public/images/icons/document-text.png +0 -0
  212. data/spec/test_app/public/images/icons/fire.png +0 -0
  213. data/spec/test_app/public/images/icons/folder-medium.png +0 -0
  214. data/spec/test_app/public/images/icons/folder.png +0 -0
  215. data/spec/test_app/public/images/icons/gear.png +0 -0
  216. data/spec/test_app/public/images/icons/globe-green.png +0 -0
  217. data/spec/test_app/public/images/icons/globe-green_light.png +0 -0
  218. data/spec/test_app/public/images/icons/globe-medium-green.png +0 -0
  219. data/spec/test_app/public/images/icons/heart-break.png +0 -0
  220. data/spec/test_app/public/images/icons/heart.png +0 -0
  221. data/spec/test_app/public/images/icons/images-flickr.png +0 -0
  222. data/spec/test_app/public/images/icons/information-balloon.png +0 -0
  223. data/spec/test_app/public/images/icons/key.png +0 -0
  224. data/spec/test_app/public/images/icons/light-bulb.png +0 -0
  225. data/spec/test_app/public/images/icons/lock--exclamation.png +0 -0
  226. data/spec/test_app/public/images/icons/lock.png +0 -0
  227. data/spec/test_app/public/images/icons/magnifier-medium.png +0 -0
  228. data/spec/test_app/public/images/icons/magnifier.png +0 -0
  229. data/spec/test_app/public/images/icons/mail.png +0 -0
  230. data/spec/test_app/public/images/icons/paper-clip-small.png +0 -0
  231. data/spec/test_app/public/images/icons/paper-clip.png +0 -0
  232. data/spec/test_app/public/images/icons/pencil.png +0 -0
  233. data/spec/test_app/public/images/icons/plus-circle.png +0 -0
  234. data/spec/test_app/public/images/icons/plus-small.png +0 -0
  235. data/spec/test_app/public/images/icons/plus.png +0 -0
  236. data/spec/test_app/public/images/icons/printer.png +0 -0
  237. data/spec/test_app/public/images/icons/question-balloon.png +0 -0
  238. data/spec/test_app/public/images/icons/question-white.png +0 -0
  239. data/spec/test_app/public/images/icons/question.png +0 -0
  240. data/spec/test_app/public/images/icons/quill.png +0 -0
  241. data/spec/test_app/public/images/icons/robot.png +0 -0
  242. data/spec/test_app/public/images/icons/ruby_16.png +0 -0
  243. data/spec/test_app/public/images/icons/ruby_2_16.png +0 -0
  244. data/spec/test_app/public/images/icons/ruby_32.png +0 -0
  245. data/spec/test_app/public/images/icons/show.png +0 -0
  246. data/spec/test_app/public/images/icons/star.png +0 -0
  247. data/spec/test_app/public/images/icons/sticky-note-text.png +0 -0
  248. data/spec/test_app/public/images/icons/telephone-fax.png +0 -0
  249. data/spec/test_app/public/images/icons/telephone-fax_light.png +0 -0
  250. data/spec/test_app/public/images/icons/telephone.png +0 -0
  251. data/spec/test_app/public/images/icons/telephone_light.png +0 -0
  252. data/spec/test_app/public/images/icons/thumb-up.png +0 -0
  253. data/spec/test_app/public/images/icons/thumb.png +0 -0
  254. data/spec/test_app/public/images/icons/tick.png +0 -0
  255. data/spec/test_app/public/images/icons/trophy-silver.png +0 -0
  256. data/spec/test_app/public/images/icons/trophy.png +0 -0
  257. data/spec/test_app/public/images/icons/user-gray.png +0 -0
  258. data/spec/test_app/public/images/icons/user-gray_gray.png +0 -0
  259. data/spec/test_app/public/images/icons/user-medium.png +0 -0
  260. data/spec/test_app/public/images/icons/user-red.png +0 -0
  261. data/spec/test_app/public/images/icons/users.png +0 -0
  262. data/spec/test_app/public/images/icons/users_gray.png +0 -0
  263. data/spec/test_app/public/images/icons/xfn.png +0 -0
  264. data/spec/test_app/public/images/legend_bg.png +0 -0
  265. data/spec/test_app/public/images/poshytip/tip-deepgray.png +0 -0
  266. data/spec/test_app/public/images/poshytip/tip-deepgray_arrows.png +0 -0
  267. data/spec/test_app/public/images/stripes_bottom_dark.png +0 -0
  268. data/spec/test_app/public/images/stripes_top_dark.png +0 -0
  269. data/spec/test_app/public/images/ui/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  270. data/spec/test_app/public/images/ui/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  271. data/spec/test_app/public/images/ui/ui-bg_flat_10_000000_40x100.png +0 -0
  272. data/spec/test_app/public/images/ui/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  273. data/spec/test_app/public/images/ui/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  274. data/spec/test_app/public/images/ui/ui-bg_glass_65_ffffff_1x400.png +0 -0
  275. data/spec/test_app/public/images/ui/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  276. data/spec/test_app/public/images/ui/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  277. data/spec/test_app/public/images/ui/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  278. data/spec/test_app/public/images/ui/ui-icons_222222_256x240.png +0 -0
  279. data/spec/test_app/public/images/ui/ui-icons_228ef1_256x240.png +0 -0
  280. data/spec/test_app/public/images/ui/ui-icons_ef8c08_256x240.png +0 -0
  281. data/spec/test_app/public/images/ui/ui-icons_ffd27a_256x240.png +0 -0
  282. data/spec/test_app/public/images/ui/ui-icons_ffffff_256x240.png +0 -0
  283. data/spec/test_app/public/javascripts/application.js +175 -0
  284. data/spec/test_app/public/javascripts/lib/jquery-1.4.2.min.js +154 -0
  285. data/spec/test_app/public/javascripts/lib/jquery-ui-1.8.5.custom.min.js +249 -0
  286. data/spec/test_app/public/javascripts/lib/jquery-ui-1.8.5.custom.min.txt +9 -0
  287. data/spec/test_app/public/javascripts/lib/jquery-ui-timepicker-addon.js +682 -0
  288. data/spec/test_app/public/javascripts/lib/jquery-ui-timepicker-addon.min.js +22 -0
  289. data/spec/test_app/public/javascripts/lib/jquery.elastic.js +6 -0
  290. data/spec/test_app/public/javascripts/lib/jquery.elastic.performance.js +128 -0
  291. data/spec/test_app/public/javascripts/lib/jquery.elastic.source.js +117 -0
  292. data/spec/test_app/public/javascripts/lib/jquery.poshytip.js +414 -0
  293. data/spec/test_app/public/javascripts/lib/jquery.poshytip.min.js +7 -0
  294. data/spec/test_app/public/javascripts/lib/jquery.ui.datepicker-de.js +23 -0
  295. data/spec/test_app/public/javascripts/lib/jrails.js +1 -0
  296. data/spec/test_app/public/javascripts/lib/multiple-autocomplete.js +39 -0
  297. data/spec/test_app/public/javascripts/lib/underscore-min.js +17 -0
  298. data/spec/test_app/public/javascripts/lib/underscore.js +704 -0
  299. data/spec/test_app/public/robots.txt +5 -0
  300. data/spec/test_app/public/stylesheets/lib/PIE.htc +77 -0
  301. data/spec/test_app/public/stylesheets/lib/PIE_uncompressed.htc +3064 -0
  302. data/spec/test_app/public/stylesheets/lib/jquery-ui-timepicker-addon.css +11 -0
  303. data/spec/test_app/public/stylesheets/lib/poshytip/tip-darkgray/tip-darkgray.css +62 -0
  304. data/spec/test_app/public/stylesheets/lib/poshytip/tip-darkgray/tip-darkgray.png +0 -0
  305. data/spec/test_app/public/stylesheets/lib/poshytip/tip-darkgray/tip-darkgray_arrows.png +0 -0
  306. data/spec/test_app/public/stylesheets/lib/poshytip/tip-deepgray/tip-deepgray.css +64 -0
  307. data/spec/test_app/public/stylesheets/lib/poshytip/tip-green/tip-green.css +57 -0
  308. data/spec/test_app/public/stylesheets/lib/poshytip/tip-green/tip-green_arrows.gif +0 -0
  309. data/spec/test_app/public/stylesheets/lib/poshytip/tip-skyblue/tip-skyblue.css +58 -0
  310. data/spec/test_app/public/stylesheets/lib/poshytip/tip-skyblue/tip-skyblue.png +0 -0
  311. data/spec/test_app/public/stylesheets/lib/poshytip/tip-skyblue/tip-skyblue_arrows.png +0 -0
  312. data/spec/test_app/public/stylesheets/lib/poshytip/tip-twitter/tip-twitter.css +59 -0
  313. data/spec/test_app/public/stylesheets/lib/poshytip/tip-twitter/tip-twitter_arrows.gif +0 -0
  314. data/spec/test_app/public/stylesheets/lib/poshytip/tip-violet/tip-violet.css +60 -0
  315. data/spec/test_app/public/stylesheets/lib/poshytip/tip-violet/tip-violet.png +0 -0
  316. data/spec/test_app/public/stylesheets/lib/poshytip/tip-violet/tip-violet_arrows.png +0 -0
  317. data/spec/test_app/public/stylesheets/lib/poshytip/tip-yellow/tip-yellow.css +60 -0
  318. data/spec/test_app/public/stylesheets/lib/poshytip/tip-yellow/tip-yellow.png +0 -0
  319. data/spec/test_app/public/stylesheets/lib/poshytip/tip-yellow/tip-yellow_arrows.png +0 -0
  320. data/spec/test_app/public/stylesheets/lib/poshytip/tip-yellowsimple/tip-yellowsimple.css +60 -0
  321. data/spec/test_app/public/stylesheets/lib/poshytip/tip-yellowsimple/tip-yellowsimple_arrows.gif +0 -0
  322. data/spec/test_app/public/stylesheets/lib/ui-lightness/jquery-ui-1.8.5.custom.css +459 -0
  323. data/spec/test_app/public/stylesheets/sass/_mixins.sass +79 -0
  324. data/spec/test_app/public/stylesheets/sass/_reset.sass +40 -0
  325. data/spec/test_app/public/stylesheets/sass/print.sass +22 -0
  326. data/spec/test_app/public/stylesheets/sass/screen.sass +866 -0
  327. data/spec/test_app/script/about +4 -0
  328. data/spec/test_app/script/autospec +6 -0
  329. data/spec/test_app/script/console +3 -0
  330. data/spec/test_app/script/cucumber +10 -0
  331. data/spec/test_app/script/dbconsole +3 -0
  332. data/spec/test_app/script/destroy +3 -0
  333. data/spec/test_app/script/generate +3 -0
  334. data/spec/test_app/script/performance/benchmarker +3 -0
  335. data/spec/test_app/script/performance/profiler +3 -0
  336. data/spec/test_app/script/plugin +3 -0
  337. data/spec/test_app/script/runner +3 -0
  338. data/spec/test_app/script/server +3 -0
  339. data/spec/test_app/script/spec +10 -0
  340. metadata +748 -0
@@ -0,0 +1,14 @@
1
+ # Utility class to provide common regular expressions.
2
+ # origin: RM
3
+ class Patterns
4
+
5
+ EMAIL = /\A[a-z0-9\+\-_\.]+@[a-z0-9]+[a-z0-9\-\.]*[a-z0-9]+\z/i
6
+ HOST = /\A[a-z0-9]+[a-z0-9\-\.]*[a-z0-9]+\z/i
7
+ URL = /(http|https):\/\/[\w\-_]+(\.[\w\-_]+)*([\w\-\.,@?^=%&:\/~\+#]*[\w\-\@?^=%&\/~\+#])?/
8
+
9
+ # Returns a regexp without start-of-string and end-of-string assertions
10
+ def self.partial(pattern)
11
+ Regexp.compile(pattern.source.sub(/^(\\A|\^)/, '').sub(/(\\z|\$)$/, ''))
12
+ end
13
+
14
+ end
@@ -0,0 +1,106 @@
1
+ # Describes what a user is allowed to do in the application.
2
+ # origin: M
3
+ class Permissions < Aegis::Permissions
4
+
5
+ role :admin
6
+ role :user
7
+ role :guest
8
+
9
+ missing_user_means { User.guest }
10
+ missing_action_means :error
11
+
12
+ namespace :admin do
13
+ resources :users do
14
+ action :deleted, :collection => true
15
+ allow :admin
16
+ end
17
+ resources :categories do
18
+ allow :admin
19
+ end
20
+ end
21
+
22
+ resource :categories do
23
+ writing do
24
+ allow :admin
25
+ end
26
+ reading do
27
+ allow :everyone
28
+ end
29
+ end
30
+
31
+ resources :conferences do
32
+ action :index, :search, :collection => true do
33
+ allow :everyone
34
+ end
35
+ action :show do
36
+ allow :everyone
37
+ end
38
+ action :update, :destroy do
39
+ allow :user, :admin do
40
+ object.user == user
41
+ end
42
+ end
43
+ action :create do
44
+ allow :user, :admin
45
+ end
46
+ action :attend, :cancel_attendance do
47
+ allow :user, :admin
48
+ end
49
+ end
50
+
51
+ resources :invitations do
52
+ action :create, :index do
53
+ allow :user, :admin
54
+ end
55
+ action :accept, :dismiss do
56
+ allow :user, :admin do
57
+ object.recipient == user
58
+ end
59
+ end
60
+ end
61
+
62
+ resources :users do
63
+ action :create do
64
+ allow :everyone
65
+ end
66
+ action :show do
67
+ allow :everyone
68
+ end
69
+ action :update do
70
+ allow :admin, :user do
71
+ user == object
72
+ end
73
+ end
74
+ action :request_friendship do
75
+ allow :user, :admin
76
+ end
77
+ action :search_all_fields, :collection => true do
78
+ allow :admin
79
+ end
80
+ end
81
+
82
+ resources :members do
83
+ action :request_friendships, :collection => true
84
+ allow :user, :admin
85
+ end
86
+
87
+ resources :friends do
88
+ allow :user, :admin
89
+ action :accept, :deny do
90
+ allow :user, :admin do
91
+ object.user == user
92
+ end
93
+ end
94
+ end
95
+
96
+ resource :own_profile do
97
+ action :access do
98
+ allow :user, :admin
99
+ end
100
+ end
101
+
102
+ action :reset_application_state do
103
+ allow :admin
104
+ end
105
+
106
+ end
@@ -0,0 +1,18 @@
1
+ # Trait to provide an inactive state to any ActiveRecord model, e.g. a class supporting soft-deletion or archival.
2
+ # origin: RM
3
+ module AfterlifeTrait
4
+
5
+ as_trait do |*options|
6
+ options = options.first || {}
7
+ adjective = options.delete(:as) || 'deleted'
8
+
9
+ with_adjective ="with_#{adjective}"
10
+
11
+ does "flag", adjective, :default => false
12
+ named_scope :active, :conditions => { adjective => false }
13
+ named_scope with_adjective, lambda { |show_perished|
14
+ { :conditions => (show_perished ? nil : { adjective => false }) }
15
+ }
16
+ end
17
+
18
+ end
@@ -0,0 +1,37 @@
1
+ # Models the pattern of a string attribute that has a fixed number of allowed choices with additional human labels.
2
+ # origin: RM
3
+ module ChoiceTrait
4
+
5
+ as_trait do |field, options|
6
+
7
+ options[:choices] = options[:choices].zip(options[:choices]).flatten if options[:no_hash]
8
+ choices = ActiveSupport::OrderedHash[*options[:choices]]
9
+
10
+ available_values = "available_#{field.to_s.pluralize}"
11
+
12
+ metaclass ||= singleton_class
13
+ metaclass.send(:define_method, available_values) do
14
+ choices
15
+ end
16
+
17
+ validates_inclusion_of field.to_sym, :in => send(available_values).keys, :allow_blank => !!options[:allow_blank]
18
+
19
+ if options.has_key?(:default)
20
+ has_defaults field.to_sym => options[:default]
21
+ end
22
+
23
+ define_method "humanized_#{field}" do
24
+ choices[send(field)]
25
+ end
26
+
27
+ if options[:query_methods]
28
+ choices.keys.each do |key|
29
+ define_method "#{key}?" do
30
+ send(field) == key
31
+ end
32
+ end
33
+ end
34
+
35
+ end
36
+
37
+ end
@@ -0,0 +1,8 @@
1
+ # Provides soft-deletion for ActiveRecord models.
2
+ # origin: RM
3
+ module DeletableTrait
4
+ as_trait do
5
+ does 'afterlife', :as => 'deleted'
6
+ does "indestructible"
7
+ end
8
+ end
@@ -0,0 +1,30 @@
1
+ # Models the pattern of a boolean attribute that must be true or false, but never nil.
2
+ # origin: RM
3
+ module FlagTrait
4
+
5
+ as_trait do |field, options|
6
+
7
+ options ||= {}
8
+
9
+ default = options[:default]
10
+ virtual = options[:virtual]
11
+ field_var = "@#{field}"
12
+ set_field = "#{field}="
13
+
14
+ validates_inclusion_of field.to_sym, :in => [true, false], :allow_nil => !!virtual
15
+ has_defaults field.to_sym => default
16
+
17
+ if virtual
18
+
19
+ attr_reader field
20
+
21
+ define_method set_field do |value|
22
+ value = ActiveRecord::ConnectionAdapters::Column.value_to_boolean(value)
23
+ instance_variable_set(field_var, value)
24
+ end
25
+
26
+ end
27
+
28
+ end
29
+
30
+ end
@@ -0,0 +1,19 @@
1
+ # Changes an ActiveRecord class so its instances cannot be destroyed.
2
+ # origin: RM
3
+ module IndestructibleTrait
4
+ as_trait do |*options|
5
+
6
+ options = options[0] || {}
7
+
8
+ before_destroy(options) do
9
+ false
10
+ end
11
+
12
+ # Allow others to check whether this is an indestructible record.
13
+ # This is not an ActiveRecord method.
14
+ def destructible?
15
+ false
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,70 @@
1
+ # Provides a virtual attribute that can be get and set like an array, but is realized into other data structure upon saving.
2
+ # origin: RM
3
+ module ListFieldTrait
4
+
5
+ # This is an array that stringifies with comma separators, so we can
6
+ # have a text field in the form for it.
7
+ class CommaSeparatedArray
8
+
9
+ include Enumerable
10
+
11
+ def initialize(list)
12
+ @list = list
13
+ end
14
+
15
+ def each(&block)
16
+ @list.each(&block)
17
+ end
18
+
19
+ def <<(element)
20
+ @list << element
21
+ end
22
+
23
+ def to_s
24
+ @list.join(', ')
25
+ end
26
+
27
+ def to_a
28
+ @list
29
+ end
30
+
31
+ def self.wrap(list)
32
+ list.is_a?(self) ? list : new(list)
33
+ end
34
+
35
+ end
36
+
37
+ as_trait do |*args|
38
+
39
+ list = args[0]
40
+ options = args[1] || {}
41
+
42
+ cast_to_integer = options[:integer]
43
+ list_variable = "@#{list}"
44
+ set_list = "#{list}="
45
+ read_list = "read_#{list}"
46
+ write_list = "write_#{list}"
47
+ write_list_if_changed = "write_#{list}_if_changed"
48
+
49
+ after_save write_list_if_changed
50
+
51
+ define_method list do
52
+ CommaSeparatedArray.wrap(instance_variable_get(list_variable) || send(read_list))
53
+ end
54
+
55
+ define_method write_list_if_changed do
56
+ list = instance_variable_get(list_variable)
57
+ send(write_list, list) if list
58
+ true
59
+ end
60
+
61
+ define_method set_list do |new_list|
62
+ new_list = new_list.split(/\s*,\s*/) if new_list.is_a?(String)
63
+ new_list.reject!(&:blank?)
64
+ new_list.collect!(&:to_i) if cast_to_integer
65
+ instance_variable_set(list_variable, new_list)
66
+ end
67
+
68
+ end
69
+
70
+ end
@@ -0,0 +1,25 @@
1
+ # Provides an attribute #full_name that is composed from #first_name and #last_name.
2
+ # origin: RM
3
+ module PersonNameTrait
4
+ as_trait do
5
+
6
+ # validates_presence_of :last_name
7
+
8
+ before_validation :store_full_name
9
+
10
+ def full_name
11
+ [first_name, last_name].select(&:present?).join(" ")
12
+ end
13
+
14
+ def name
15
+ full_name
16
+ end
17
+
18
+ private
19
+
20
+ def store_full_name
21
+ self.full_name = full_name
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,71 @@
1
+ # Provides a search scope with Google-esque syntax for ActiveRecord models, e.g. "foo bar date:20090511 baz"
2
+ # origin: RM
3
+ module SearchableTrait
4
+
5
+ TEXT_QUERY = /(?:"([^"]+)"|([\w\-@\._]+))/
6
+ FIELD_QUERY = /(\w+)\:#{TEXT_QUERY}/
7
+
8
+ as_trait do |options|
9
+
10
+ text_field = options[:text_means] || :text # the field we're searching when no field is given
11
+
12
+ class << self
13
+ attr_accessor :defined_searchers
14
+ end
15
+
16
+ singleton_class.send :define_method, :search do |query|
17
+ query = query.dup # we are going to delete substrings in-place
18
+ scope = scoped({})
19
+ scope = filter_by_field_queries(scope, query)
20
+ scope = filter_by_text_queries(scope, query)
21
+ scope
22
+ end
23
+
24
+ private
25
+
26
+ singleton_class.send :define_method, :search_by do |*fields, &searcher|
27
+ self.defined_searchers ||= {}
28
+ fields.each do |field|
29
+ defined_searchers[field.to_s.downcase] = true
30
+ # we need to define the searcher as an actual method because of the way scopes delegate methods to the AR class
31
+ singleton_class.send :define_method, "search_by_#{field}", &searcher
32
+ end
33
+ end
34
+
35
+ singleton_class.send :define_method, :filter_by_field_queries do |scope, query|
36
+ while query.sub!(SearchableTrait::FIELD_QUERY, '')
37
+ field = $1
38
+ value = "#{$2}#{$3}"
39
+ scope = search_by_field(scope, field, value)
40
+ end
41
+ scope
42
+ end
43
+
44
+ singleton_class.send :define_method, :filter_by_text_queries do |scope, query|
45
+ while query.sub!(SearchableTrait::TEXT_QUERY, '')
46
+ value = "#{$1}#{$2}"
47
+ scope = search_by_field(scope, text_field, value)
48
+ end
49
+ scope
50
+ end
51
+
52
+ singleton_class.send :define_method, :search_by_field do |scope, field, value|
53
+ normalized_field = field.to_s.downcase
54
+ if defined_searchers[normalized_field]
55
+ scope = scope.send("search_by_#{normalized_field}", value)
56
+ else
57
+ scope = scope.find_nothing
58
+ end
59
+ scope
60
+ end
61
+
62
+ singleton_class.send :define_method, :find_nothing do
63
+ scoped(:conditions => "1=2")
64
+ end
65
+
66
+ search_by text_field do |text|
67
+ scoped(:conditions => Util.like_query(text_field, text))
68
+ end
69
+
70
+ end
71
+ end
@@ -0,0 +1,24 @@
1
+ # Macro to implement a comparison method for Ruby classes.
2
+ # origin: RM
3
+ module SortableTrait
4
+
5
+ as_trait do |options|
6
+
7
+ send(:define_method, :"<=>") do |other|
8
+ fields = Array(options[:by])
9
+ cmp = 0
10
+ for field in fields
11
+ left = send(field)
12
+ left = left.downcase if left.respond_to?(:downcase)
13
+ right = other.send(field)
14
+ right = right.downcase if right.respond_to?(:downcase)
15
+ cmp = left <=> right
16
+ break unless cmp == 0
17
+ end
18
+ cmp *= -1 if options[:descending]
19
+ cmp
20
+ end
21
+
22
+ end
23
+
24
+ end
@@ -0,0 +1,33 @@
1
+ # Code to authenticate against a user database.
2
+ # origin: RM
3
+ module User::AuthenticationTrait
4
+ as_trait do
5
+
6
+ include Clearance::User
7
+
8
+ validates_length_of :password, :minimum => 3, :allow_blank => true
9
+ validates_format_of :username, :with => /^[a-z][a-z0-9\.\-_öÖüÜäÄß]+$/mi
10
+ validates_uniqueness_of :username, :case_sensitive => false
11
+
12
+ does 'flag', :locked, :default => false
13
+
14
+ # Allow to login with either email or screen_name
15
+ def self.authenticate(username_or_email, password)
16
+ return nil unless user = find(:first, :conditions => ['email = ? OR username = ?', username_or_email, username_or_email])
17
+ return user if user.authenticated?(password)
18
+ end
19
+
20
+ def email_confirmed?
21
+ true
22
+ end
23
+
24
+ def account_disabled?
25
+ locked? || deleted?
26
+ end
27
+
28
+ def self.guest
29
+ @guest ||= User.new(:role_name => 'guest')
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,17 @@
1
+ # Hooks up the aegis gem so users can be given roles and be queried for permissions.
2
+ # origin: RM
3
+ module User::AuthorizationTrait
4
+ as_trait do
5
+
6
+ has_role :default => 'user'
7
+ validates_role
8
+
9
+ def self.available_roles
10
+ labeler = lambda { |role| I18n.t("roles.#{role.name}") }
11
+ Permissions.roles.sort_by(&labeler).collect_ordered_hash do |role|
12
+ [role.name, labeler.call(role)]
13
+ end
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,42 @@
1
+ # Manages friends and friendship requests for users.
2
+ # origin: M
3
+ module User::FriendsTrait
4
+ as_trait do
5
+
6
+ has_many :sent_friendship_requests, :class_name => 'FriendshipRequest', :foreign_key => 'requesting_user_id'
7
+ has_many :friendship_requests
8
+
9
+ has_many :friendships
10
+ has_many :friends, :through => :friendships, :order => 'username'
11
+
12
+ def in_contact_with?(other_user)
13
+ friends_with?(other_user) or sent_friendship_requests.collect(&:user_id).include?(other_user.id)
14
+ end
15
+
16
+ def friends_with?(other_user)
17
+ friendships.collect(&:friend_id).include? other_user.id
18
+ end
19
+
20
+ def can_become_friends_with?(other_user)
21
+ self != other_user and not in_contact_with? other_user
22
+ end
23
+
24
+ def status_towards(other_user)
25
+ if friends_with?(other_user)
26
+ 'in_contact'
27
+ elsif sent_friendship_requests.collect(&:user_id).include?(other_user.id)
28
+ 'RCD_sent'
29
+ elsif friendship_requests.collect(&:requesting_user_id).include?(other_user.id)
30
+ 'RCD_received'
31
+ else
32
+ 'no_contact'
33
+ end
34
+ end
35
+
36
+ def contacts
37
+ user_ids = (friend_ids + sent_friendship_requests.collect(&:user_id) + friendship_requests.collect(&:requesting_user_id)).uniq
38
+ User.all(:conditions => {:id => user_ids})
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,43 @@
1
+ # Provides search for user records.
2
+ # origin: M
3
+ module User::SearchTrait
4
+ as_trait do
5
+
6
+ TEXT_QUERY = /(?:"([^"]+)"|([\w\-@\._]+))/
7
+
8
+ # Returns users matching the given query.
9
+ # Users may search additional fields of a user they are friends with.
10
+ # Admins may search all fields.
11
+ def self.search(query, searching_user)
12
+ friend_ids = searching_user.friend_ids
13
+ like_username = find_words_in_field('users.username', query)
14
+ like_full_name = find_words_in_field('users.full_name', query)
15
+ like_email = find_words_in_field('users.email', query)
16
+ conditions = if searching_user.may_search_all_fields_users?
17
+ "(#{like_username}) OR (#{like_full_name}) OR (#{like_email})"
18
+ elsif friend_ids.any?
19
+ is_friend = "users.id IN (#{friend_ids.join ', '})"
20
+ "(#{is_friend}) AND (#{like_full_name}) OR (#{like_username})"
21
+ else
22
+ like_username
23
+ end
24
+ scoped :conditions => conditions
25
+ end
26
+
27
+ private
28
+
29
+ def self.find_words_in_field(field, query)
30
+ collect_words(query) do |word|
31
+ sanitize_sql_for_conditions(Util.like_query(field, word))
32
+ end.join(' AND ')
33
+ end
34
+
35
+ def self.collect_words(query, &block)
36
+ query.scan(TEXT_QUERY).collect do |phrase_match, word_match|
37
+ word = "#{phrase_match}#{word_match}"
38
+ block.call(word)
39
+ end
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,61 @@
1
+ # Models a registered user.
2
+ # origin: RM
3
+ class User < ActiveRecord::Base
4
+ does 'user/authentication'
5
+ does 'user/authorization'
6
+ does 'user/friends'
7
+ does 'user/search'
8
+ does 'deletable'
9
+ does 'sortable', :by => :username
10
+ named_scope :by_username, :order => :username
11
+
12
+ has_many :attendances
13
+ has_many :conferences, :through => :attendances
14
+
15
+ validates_presence_of :full_name, :town, :country, :username
16
+ has_many :received_invitations, :class_name => 'Invitation', :foreign_key => 'recipient_id'
17
+ has_many :sent_invitations, :class_name => 'Invitation', :foreign_key => 'sender_id'
18
+
19
+ has_attached_file :avatar
20
+
21
+
22
+ def sees_details_of?(other_user, force_visible = false)
23
+ force_visible || self == other_user || friends_with?(other_user)
24
+ end
25
+
26
+ def username_with_full_name
27
+ "#{username} (#{full_name})"
28
+ end
29
+
30
+ def name_for(other_user, force_visible = false)
31
+ if sees_details_of?(other_user, force_visible)
32
+ other_user.username_with_full_name
33
+ else
34
+ other_user.username
35
+ end
36
+ end
37
+
38
+ def email_for(other_user, force_visible = false)
39
+ if sees_details_of?(other_user, force_visible)
40
+ other_user.email
41
+ else
42
+ '–'
43
+ end
44
+ end
45
+
46
+ def self.create_admin!
47
+ create! :username => 'admin',
48
+ :password => 'admin',
49
+ :password_confirmation => 'admin',
50
+ :email => 'admin@plat-forms.org',
51
+ :full_name => 'Plat_Forms 2011',
52
+ :town => 'Nürnberg',
53
+ :country => 'Germany',
54
+ :role_name => 'admin'
55
+ end
56
+
57
+ def self.import(path)
58
+ YAML.load(path)
59
+ end
60
+
61
+ end
@@ -0,0 +1,19 @@
1
+ # Utility methods.
2
+ # origin: RM
3
+ module Util
4
+
5
+ extend self
6
+
7
+ def collect_ids(records_or_ids)
8
+ Array(records_or_ids).collect { |o| o.is_a?(ActiveRecord::Base) ? o.id : o }
9
+ end
10
+
11
+ def like_query(field, query)
12
+ ["#{field} LIKE ?", "%#{escape_for_like_query(query)}%"]
13
+ end
14
+
15
+ def escape_for_like_query(word)
16
+ word.gsub("%", "\\%").gsub("_", "\\_")
17
+ end
18
+
19
+ end
@@ -0,0 +1,18 @@
1
+ -# Partial for a category form as shown to admins.
2
+ -# origin: M
3
+
4
+ - form_for [:admin, @category] do |form|
5
+ %dl
6
+ %dt
7
+ = form.label :name
8
+ %dd
9
+ = form.error_message_on :name
10
+ = form.text_field :name
11
+ %dt
12
+ = form.label :parent_id
13
+ %dd
14
+ = form.error_message_on :parent_id
15
+ = form.select :parent_id, form.object.available_parents, :include_blank => true
16
+
17
+ = boring_save_cancel_buttons
18
+
@@ -0,0 +1,17 @@
1
+ -# Partial for a category list as shown to admins.
2
+ -# origin: M
3
+
4
+ - categories = local_assigns[:categories] || @categories
5
+
6
+ - if categories.present?
7
+ %table.grid
8
+ %tr
9
+ %th= Category.human_attribute_name :name
10
+ - for category in categories
11
+ %tr
12
+ %td= link_to(icon(:category, category.name), [:admin, category])
13
+ = pagination categories
14
+ - else
15
+ .none
16
+ No categories found.
17
+