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,704 @@
1
+ // Underscore.js
2
+ // (c) 2010 Jeremy Ashkenas, DocumentCloud Inc.
3
+ // Underscore is freely distributable under the terms of the MIT license.
4
+ // Portions of Underscore are inspired by or borrowed from Prototype.js,
5
+ // Oliver Steele's Functional, and John Resig's Micro-Templating.
6
+ // For all details and documentation:
7
+ // http://documentcloud.github.com/underscore
8
+
9
+ (function() {
10
+ // ------------------------- Baseline setup ---------------------------------
11
+
12
+ // Establish the root object, "window" in the browser, or "global" on the server.
13
+ var root = this;
14
+
15
+ // Save the previous value of the "_" variable.
16
+ var previousUnderscore = root._;
17
+
18
+ // Establish the object that gets thrown to break out of a loop iteration.
19
+ var breaker = typeof StopIteration !== 'undefined' ? StopIteration : '__break__';
20
+
21
+ // Quick regexp-escaping function, because JS doesn't have RegExp.escape().
22
+ var escapeRegExp = function(s) { return s.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1'); };
23
+
24
+ // Save bytes in the minified (but not gzipped) version:
25
+ var ArrayProto = Array.prototype, ObjProto = Object.prototype;
26
+
27
+ // Create quick reference variables for speed access to core prototypes.
28
+ var slice = ArrayProto.slice,
29
+ unshift = ArrayProto.unshift,
30
+ toString = ObjProto.toString,
31
+ hasOwnProperty = ObjProto.hasOwnProperty,
32
+ propertyIsEnumerable = ObjProto.propertyIsEnumerable;
33
+
34
+ // All ECMA5 native implementations we hope to use are declared here.
35
+ var
36
+ nativeForEach = ArrayProto.forEach,
37
+ nativeMap = ArrayProto.map,
38
+ nativeReduce = ArrayProto.reduce,
39
+ nativeReduceRight = ArrayProto.reduceRight,
40
+ nativeFilter = ArrayProto.filter,
41
+ nativeEvery = ArrayProto.every,
42
+ nativeSome = ArrayProto.some,
43
+ nativeIndexOf = ArrayProto.indexOf,
44
+ nativeLastIndexOf = ArrayProto.lastIndexOf,
45
+ nativeIsArray = Array.isArray,
46
+ nativeKeys = Object.keys;
47
+
48
+ // Create a safe reference to the Underscore object for use below.
49
+ var _ = function(obj) { return new wrapper(obj); };
50
+
51
+ // Export the Underscore object for CommonJS.
52
+ if (typeof exports !== 'undefined') exports._ = _;
53
+
54
+ // Export underscore to global scope.
55
+ root._ = _;
56
+
57
+ // Current version.
58
+ _.VERSION = '1.0.4';
59
+
60
+ // ------------------------ Collection Functions: ---------------------------
61
+
62
+ // The cornerstone, an each implementation.
63
+ // Handles objects implementing forEach, arrays, and raw objects.
64
+ // Delegates to JavaScript 1.6's native forEach if available.
65
+ var each = _.forEach = function(obj, iterator, context) {
66
+ try {
67
+ if (nativeForEach && obj.forEach === nativeForEach) {
68
+ obj.forEach(iterator, context);
69
+ } else if (_.isNumber(obj.length)) {
70
+ for (var i = 0, l = obj.length; i < l; i++) iterator.call(context, obj[i], i, obj);
71
+ } else {
72
+ for (var key in obj) {
73
+ if (hasOwnProperty.call(obj, key)) iterator.call(context, obj[key], key, obj);
74
+ }
75
+ }
76
+ } catch(e) {
77
+ if (e != breaker) throw e;
78
+ }
79
+ return obj;
80
+ };
81
+
82
+ // Return the results of applying the iterator to each element.
83
+ // Delegates to JavaScript 1.6's native map if available.
84
+ _.map = function(obj, iterator, context) {
85
+ if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
86
+ var results = [];
87
+ each(obj, function(value, index, list) {
88
+ results.push(iterator.call(context, value, index, list));
89
+ });
90
+ return results;
91
+ };
92
+
93
+ // Reduce builds up a single result from a list of values, aka inject, or foldl.
94
+ // Delegates to JavaScript 1.8's native reduce if available.
95
+ _.reduce = function(obj, memo, iterator, context) {
96
+ if (nativeReduce && obj.reduce === nativeReduce) return obj.reduce(_.bind(iterator, context), memo);
97
+ each(obj, function(value, index, list) {
98
+ memo = iterator.call(context, memo, value, index, list);
99
+ });
100
+ return memo;
101
+ };
102
+
103
+ // The right-associative version of reduce, also known as foldr. Uses
104
+ // Delegates to JavaScript 1.8's native reduceRight if available.
105
+ _.reduceRight = function(obj, memo, iterator, context) {
106
+ if (nativeReduceRight && obj.reduceRight === nativeReduceRight) return obj.reduceRight(_.bind(iterator, context), memo);
107
+ var reversed = _.clone(_.toArray(obj)).reverse();
108
+ return _.reduce(reversed, memo, iterator, context);
109
+ };
110
+
111
+ // Return the first value which passes a truth test.
112
+ _.detect = function(obj, iterator, context) {
113
+ var result;
114
+ each(obj, function(value, index, list) {
115
+ if (iterator.call(context, value, index, list)) {
116
+ result = value;
117
+ _.breakLoop();
118
+ }
119
+ });
120
+ return result;
121
+ };
122
+
123
+ // Return all the elements that pass a truth test.
124
+ // Delegates to JavaScript 1.6's native filter if available.
125
+ _.filter = function(obj, iterator, context) {
126
+ if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
127
+ var results = [];
128
+ each(obj, function(value, index, list) {
129
+ iterator.call(context, value, index, list) && results.push(value);
130
+ });
131
+ return results;
132
+ };
133
+
134
+ // Return all the elements for which a truth test fails.
135
+ _.reject = function(obj, iterator, context) {
136
+ var results = [];
137
+ each(obj, function(value, index, list) {
138
+ !iterator.call(context, value, index, list) && results.push(value);
139
+ });
140
+ return results;
141
+ };
142
+
143
+ // Determine whether all of the elements match a truth test.
144
+ // Delegates to JavaScript 1.6's native every if available.
145
+ _.every = function(obj, iterator, context) {
146
+ iterator = iterator || _.identity;
147
+ if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
148
+ var result = true;
149
+ each(obj, function(value, index, list) {
150
+ if (!(result = result && iterator.call(context, value, index, list))) _.breakLoop();
151
+ });
152
+ return result;
153
+ };
154
+
155
+ // Determine if at least one element in the object matches a truth test.
156
+ // Delegates to JavaScript 1.6's native some if available.
157
+ _.some = function(obj, iterator, context) {
158
+ iterator = iterator || _.identity;
159
+ if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
160
+ var result = false;
161
+ each(obj, function(value, index, list) {
162
+ if (result = iterator.call(context, value, index, list)) _.breakLoop();
163
+ });
164
+ return result;
165
+ };
166
+
167
+ // Determine if a given value is included in the array or object using '==='.
168
+ _.include = function(obj, target) {
169
+ if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
170
+ var found = false;
171
+ each(obj, function(value) {
172
+ if (found = value === target) _.breakLoop();
173
+ });
174
+ return found;
175
+ };
176
+
177
+ // Invoke a method with arguments on every item in a collection.
178
+ _.invoke = function(obj, method) {
179
+ var args = _.rest(arguments, 2);
180
+ return _.map(obj, function(value) {
181
+ return (method ? value[method] : value).apply(value, args);
182
+ });
183
+ };
184
+
185
+ // Convenience version of a common use case of map: fetching a property.
186
+ _.pluck = function(obj, key) {
187
+ return _.map(obj, function(value){ return value[key]; });
188
+ };
189
+
190
+ // Return the maximum item or (item-based computation).
191
+ _.max = function(obj, iterator, context) {
192
+ if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);
193
+ var result = {computed : -Infinity};
194
+ each(obj, function(value, index, list) {
195
+ var computed = iterator ? iterator.call(context, value, index, list) : value;
196
+ computed >= result.computed && (result = {value : value, computed : computed});
197
+ });
198
+ return result.value;
199
+ };
200
+
201
+ // Return the minimum element (or element-based computation).
202
+ _.min = function(obj, iterator, context) {
203
+ if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);
204
+ var result = {computed : Infinity};
205
+ each(obj, function(value, index, list) {
206
+ var computed = iterator ? iterator.call(context, value, index, list) : value;
207
+ computed < result.computed && (result = {value : value, computed : computed});
208
+ });
209
+ return result.value;
210
+ };
211
+
212
+ // Sort the object's values by a criterion produced by an iterator.
213
+ _.sortBy = function(obj, iterator, context) {
214
+ return _.pluck(_.map(obj, function(value, index, list) {
215
+ return {
216
+ value : value,
217
+ criteria : iterator.call(context, value, index, list)
218
+ };
219
+ }).sort(function(left, right) {
220
+ var a = left.criteria, b = right.criteria;
221
+ return a < b ? -1 : a > b ? 1 : 0;
222
+ }), 'value');
223
+ };
224
+
225
+ // Use a comparator function to figure out at what index an object should
226
+ // be inserted so as to maintain order. Uses binary search.
227
+ _.sortedIndex = function(array, obj, iterator) {
228
+ iterator = iterator || _.identity;
229
+ var low = 0, high = array.length;
230
+ while (low < high) {
231
+ var mid = (low + high) >> 1;
232
+ iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;
233
+ }
234
+ return low;
235
+ };
236
+
237
+ // Convert anything iterable into a real, live array.
238
+ _.toArray = function(iterable) {
239
+ if (!iterable) return [];
240
+ if (iterable.toArray) return iterable.toArray();
241
+ if (_.isArray(iterable)) return iterable;
242
+ if (_.isArguments(iterable)) return slice.call(iterable);
243
+ return _.values(iterable);
244
+ };
245
+
246
+ // Return the number of elements in an object.
247
+ _.size = function(obj) {
248
+ return _.toArray(obj).length;
249
+ };
250
+
251
+ // -------------------------- Array Functions: ------------------------------
252
+
253
+ // Get the first element of an array. Passing "n" will return the first N
254
+ // values in the array. Aliased as "head". The "guard" check allows it to work
255
+ // with _.map.
256
+ _.first = function(array, n, guard) {
257
+ return n && !guard ? slice.call(array, 0, n) : array[0];
258
+ };
259
+
260
+ // Returns everything but the first entry of the array. Aliased as "tail".
261
+ // Especially useful on the arguments object. Passing an "index" will return
262
+ // the rest of the values in the array from that index onward. The "guard"
263
+ //check allows it to work with _.map.
264
+ _.rest = function(array, index, guard) {
265
+ return slice.call(array, _.isUndefined(index) || guard ? 1 : index);
266
+ };
267
+
268
+ // Get the last element of an array.
269
+ _.last = function(array) {
270
+ return array[array.length - 1];
271
+ };
272
+
273
+ // Trim out all falsy values from an array.
274
+ _.compact = function(array) {
275
+ return _.filter(array, function(value){ return !!value; });
276
+ };
277
+
278
+ // Return a completely flattened version of an array.
279
+ _.flatten = function(array) {
280
+ return _.reduce(array, [], function(memo, value) {
281
+ if (_.isArray(value)) return memo.concat(_.flatten(value));
282
+ memo.push(value);
283
+ return memo;
284
+ });
285
+ };
286
+
287
+ // Return a version of the array that does not contain the specified value(s).
288
+ _.without = function(array) {
289
+ var values = _.rest(arguments);
290
+ return _.filter(array, function(value){ return !_.include(values, value); });
291
+ };
292
+
293
+ // Produce a duplicate-free version of the array. If the array has already
294
+ // been sorted, you have the option of using a faster algorithm.
295
+ _.uniq = function(array, isSorted) {
296
+ return _.reduce(array, [], function(memo, el, i) {
297
+ if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) memo.push(el);
298
+ return memo;
299
+ });
300
+ };
301
+
302
+ // Produce an array that contains every item shared between all the
303
+ // passed-in arrays.
304
+ _.intersect = function(array) {
305
+ var rest = _.rest(arguments);
306
+ return _.filter(_.uniq(array), function(item) {
307
+ return _.every(rest, function(other) {
308
+ return _.indexOf(other, item) >= 0;
309
+ });
310
+ });
311
+ };
312
+
313
+ // Zip together multiple lists into a single array -- elements that share
314
+ // an index go together.
315
+ _.zip = function() {
316
+ var args = _.toArray(arguments);
317
+ var length = _.max(_.pluck(args, 'length'));
318
+ var results = new Array(length);
319
+ for (var i = 0; i < length; i++) results[i] = _.pluck(args, String(i));
320
+ return results;
321
+ };
322
+
323
+ // If the browser doesn't supply us with indexOf (I'm looking at you, MSIE),
324
+ // we need this function. Return the position of the first occurence of an
325
+ // item in an array, or -1 if the item is not included in the array.
326
+ // Delegates to JavaScript 1.8's native indexOf if available.
327
+ _.indexOf = function(array, item) {
328
+ if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);
329
+ for (var i = 0, l = array.length; i < l; i++) if (array[i] === item) return i;
330
+ return -1;
331
+ };
332
+
333
+
334
+ // Delegates to JavaScript 1.6's native lastIndexOf if available.
335
+ _.lastIndexOf = function(array, item) {
336
+ if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);
337
+ var i = array.length;
338
+ while (i--) if (array[i] === item) return i;
339
+ return -1;
340
+ };
341
+
342
+ // Generate an integer Array containing an arithmetic progression. A port of
343
+ // the native Python range() function. See:
344
+ // http://docs.python.org/library/functions.html#range
345
+ _.range = function(start, stop, step) {
346
+ var a = _.toArray(arguments);
347
+ var solo = a.length <= 1;
348
+ var start = solo ? 0 : a[0], stop = solo ? a[0] : a[1], step = a[2] || 1;
349
+ var len = Math.ceil((stop - start) / step);
350
+ if (len <= 0) return [];
351
+ var range = new Array(len);
352
+ for (var i = start, idx = 0; true; i += step) {
353
+ if ((step > 0 ? i - stop : stop - i) >= 0) return range;
354
+ range[idx++] = i;
355
+ }
356
+ };
357
+
358
+ // ----------------------- Function Functions: ------------------------------
359
+
360
+ // Create a function bound to a given object (assigning 'this', and arguments,
361
+ // optionally). Binding with arguments is also known as 'curry'.
362
+ _.bind = function(func, obj) {
363
+ var args = _.rest(arguments, 2);
364
+ return function() {
365
+ return func.apply(obj || {}, args.concat(_.toArray(arguments)));
366
+ };
367
+ };
368
+
369
+ // Bind all of an object's methods to that object. Useful for ensuring that
370
+ // all callbacks defined on an object belong to it.
371
+ _.bindAll = function(obj) {
372
+ var funcs = _.rest(arguments);
373
+ if (funcs.length == 0) funcs = _.functions(obj);
374
+ each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
375
+ return obj;
376
+ };
377
+
378
+ // Memoize an expensive function by storing its results.
379
+ _.memoize = function(func, hasher) {
380
+ var memo = {};
381
+ hasher = hasher || _.identity;
382
+ return function() {
383
+ var key = hasher.apply(this, arguments);
384
+ return key in memo ? memo[key] : (memo[key] = func.apply(this, arguments));
385
+ };
386
+ };
387
+
388
+ // Delays a function for the given number of milliseconds, and then calls
389
+ // it with the arguments supplied.
390
+ _.delay = function(func, wait) {
391
+ var args = _.rest(arguments, 2);
392
+ return setTimeout(function(){ return func.apply(func, args); }, wait);
393
+ };
394
+
395
+ // Defers a function, scheduling it to run after the current call stack has
396
+ // cleared.
397
+ _.defer = function(func) {
398
+ return _.delay.apply(_, [func, 1].concat(_.rest(arguments)));
399
+ };
400
+
401
+ // Returns the first function passed as an argument to the second,
402
+ // allowing you to adjust arguments, run code before and after, and
403
+ // conditionally execute the original function.
404
+ _.wrap = function(func, wrapper) {
405
+ return function() {
406
+ var args = [func].concat(_.toArray(arguments));
407
+ return wrapper.apply(wrapper, args);
408
+ };
409
+ };
410
+
411
+ // Returns a function that is the composition of a list of functions, each
412
+ // consuming the return value of the function that follows.
413
+ _.compose = function() {
414
+ var funcs = _.toArray(arguments);
415
+ return function() {
416
+ var args = _.toArray(arguments);
417
+ for (var i=funcs.length-1; i >= 0; i--) {
418
+ args = [funcs[i].apply(this, args)];
419
+ }
420
+ return args[0];
421
+ };
422
+ };
423
+
424
+ // ------------------------- Object Functions: ------------------------------
425
+
426
+ // Retrieve the names of an object's properties.
427
+ // Delegates to ECMA5's native Object.keys
428
+ _.keys = nativeKeys || function(obj) {
429
+ if (_.isArray(obj)) return _.range(0, obj.length);
430
+ var keys = [];
431
+ for (var key in obj) if (hasOwnProperty.call(obj, key)) keys.push(key);
432
+ return keys;
433
+ };
434
+
435
+ // Retrieve the values of an object's properties.
436
+ _.values = function(obj) {
437
+ return _.map(obj, _.identity);
438
+ };
439
+
440
+ // Return a sorted list of the function names available on the object.
441
+ _.functions = function(obj) {
442
+ return _.filter(_.keys(obj), function(key){ return _.isFunction(obj[key]); }).sort();
443
+ };
444
+
445
+ // Extend a given object with all the properties in passed-in object(s).
446
+ _.extend = function(obj) {
447
+ each(_.rest(arguments), function(source) {
448
+ for (var prop in source) obj[prop] = source[prop];
449
+ });
450
+ return obj;
451
+ };
452
+
453
+ // Create a (shallow-cloned) duplicate of an object.
454
+ _.clone = function(obj) {
455
+ if (_.isArray(obj)) return obj.slice(0);
456
+ return _.extend({}, obj);
457
+ };
458
+
459
+ // Invokes interceptor with the obj, and then returns obj.
460
+ // The primary purpose of this method is to "tap into" a method chain, in order to perform operations on intermediate results within the chain.
461
+ _.tap = function(obj, interceptor) {
462
+ interceptor(obj);
463
+ return obj;
464
+ };
465
+
466
+ // Perform a deep comparison to check if two objects are equal.
467
+ _.isEqual = function(a, b) {
468
+ // Check object identity.
469
+ if (a === b) return true;
470
+ // Different types?
471
+ var atype = typeof(a), btype = typeof(b);
472
+ if (atype != btype) return false;
473
+ // Basic equality test (watch out for coercions).
474
+ if (a == b) return true;
475
+ // One is falsy and the other truthy.
476
+ if ((!a && b) || (a && !b)) return false;
477
+ // One of them implements an isEqual()?
478
+ if (a.isEqual) return a.isEqual(b);
479
+ // Check dates' integer values.
480
+ if (_.isDate(a) && _.isDate(b)) return a.getTime() === b.getTime();
481
+ // Both are NaN?
482
+ if (_.isNaN(a) && _.isNaN(b)) return false;
483
+ // Compare regular expressions.
484
+ if (_.isRegExp(a) && _.isRegExp(b))
485
+ return a.source === b.source &&
486
+ a.global === b.global &&
487
+ a.ignoreCase === b.ignoreCase &&
488
+ a.multiline === b.multiline;
489
+ // If a is not an object by this point, we can't handle it.
490
+ if (atype !== 'object') return false;
491
+ // Check for different array lengths before comparing contents.
492
+ if (a.length && (a.length !== b.length)) return false;
493
+ // Nothing else worked, deep compare the contents.
494
+ var aKeys = _.keys(a), bKeys = _.keys(b);
495
+ // Different object sizes?
496
+ if (aKeys.length != bKeys.length) return false;
497
+ // Recursive comparison of contents.
498
+ for (var key in a) if (!(key in b) || !_.isEqual(a[key], b[key])) return false;
499
+ return true;
500
+ };
501
+
502
+ // Is a given array or object empty?
503
+ _.isEmpty = function(obj) {
504
+ if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
505
+ for (var key in obj) if (hasOwnProperty.call(obj, key)) return false;
506
+ return true;
507
+ };
508
+
509
+ // Is a given value a DOM element?
510
+ _.isElement = function(obj) {
511
+ return !!(obj && obj.nodeType == 1);
512
+ };
513
+
514
+ // Is a given value an array?
515
+ // Delegates to ECMA5's native Array.isArray
516
+ _.isArray = nativeIsArray || function(obj) {
517
+ return !!(obj && obj.concat && obj.unshift && !obj.callee);
518
+ };
519
+
520
+ // Is a given variable an arguments object?
521
+ _.isArguments = function(obj) {
522
+ return obj && obj.callee;
523
+ };
524
+
525
+ // Is a given value a function?
526
+ _.isFunction = function(obj) {
527
+ return !!(obj && obj.constructor && obj.call && obj.apply);
528
+ };
529
+
530
+ // Is a given value a string?
531
+ _.isString = function(obj) {
532
+ return !!(obj === '' || (obj && obj.charCodeAt && obj.substr));
533
+ };
534
+
535
+ // Is a given value a number?
536
+ _.isNumber = function(obj) {
537
+ return (obj === +obj) || (toString.call(obj) === '[object Number]');
538
+ };
539
+
540
+ // Is a given value a boolean?
541
+ _.isBoolean = function(obj) {
542
+ return obj === true || obj === false;
543
+ };
544
+
545
+ // Is a given value a date?
546
+ _.isDate = function(obj) {
547
+ return !!(obj && obj.getTimezoneOffset && obj.setUTCFullYear);
548
+ };
549
+
550
+ // Is the given value a regular expression?
551
+ _.isRegExp = function(obj) {
552
+ return !!(obj && obj.test && obj.exec && (obj.ignoreCase || obj.ignoreCase === false));
553
+ };
554
+
555
+ // Is the given value NaN -- this one is interesting. NaN != NaN, and
556
+ // isNaN(undefined) == true, so we make sure it's a number first.
557
+ _.isNaN = function(obj) {
558
+ return _.isNumber(obj) && isNaN(obj);
559
+ };
560
+
561
+ // Is a given value equal to null?
562
+ _.isNull = function(obj) {
563
+ return obj === null;
564
+ };
565
+
566
+ // Is a given variable undefined?
567
+ _.isUndefined = function(obj) {
568
+ return typeof obj == 'undefined';
569
+ };
570
+
571
+ // -------------------------- Utility Functions: ----------------------------
572
+
573
+ // Run Underscore.js in noConflict mode, returning the '_' variable to its
574
+ // previous owner. Returns a reference to the Underscore object.
575
+ _.noConflict = function() {
576
+ root._ = previousUnderscore;
577
+ return this;
578
+ };
579
+
580
+ // Keep the identity function around for default iterators.
581
+ _.identity = function(value) {
582
+ return value;
583
+ };
584
+
585
+ // Run a function n times.
586
+ _.times = function (n, iterator, context) {
587
+ for (var i = 0; i < n; i++) iterator.call(context, i);
588
+ };
589
+
590
+ // Break out of the middle of an iteration.
591
+ _.breakLoop = function() {
592
+ throw breaker;
593
+ };
594
+
595
+ // Add your own custom functions to the Underscore object, ensuring that
596
+ // they're correctly added to the OOP wrapper as well.
597
+ _.mixin = function(obj) {
598
+ each(_.functions(obj), function(name){
599
+ addToWrapper(name, _[name] = obj[name]);
600
+ });
601
+ };
602
+
603
+ // Generate a unique integer id (unique within the entire client session).
604
+ // Useful for temporary DOM ids.
605
+ var idCounter = 0;
606
+ _.uniqueId = function(prefix) {
607
+ var id = idCounter++;
608
+ return prefix ? prefix + id : id;
609
+ };
610
+
611
+ // By default, Underscore uses ERB-style template delimiters, change the
612
+ // following template settings to use alternative delimiters.
613
+ _.templateSettings = {
614
+ start : '<%',
615
+ end : '%>',
616
+ interpolate : /<%=(.+?)%>/g
617
+ };
618
+
619
+ // JavaScript templating a-la ERB, pilfered from John Resig's
620
+ // "Secrets of the JavaScript Ninja", page 83.
621
+ // Single-quote fix from Rick Strahl's version.
622
+ // With alterations for arbitrary delimiters.
623
+ _.template = function(str, data) {
624
+ var c = _.templateSettings;
625
+ var endMatch = new RegExp("'(?=[^"+c.end.substr(0, 1)+"]*"+escapeRegExp(c.end)+")","g");
626
+ var fn = new Function('obj',
627
+ 'var p=[],print=function(){p.push.apply(p,arguments);};' +
628
+ 'with(obj){p.push(\'' +
629
+ str.replace(/[\r\t\n]/g, " ")
630
+ .replace(endMatch,"\t")
631
+ .split("'").join("\\'")
632
+ .split("\t").join("'")
633
+ .replace(c.interpolate, "',$1,'")
634
+ .split(c.start).join("');")
635
+ .split(c.end).join("p.push('")
636
+ + "');}return p.join('');");
637
+ return data ? fn(data) : fn;
638
+ };
639
+
640
+ // ------------------------------- Aliases ----------------------------------
641
+
642
+ _.each = _.forEach;
643
+ _.foldl = _.inject = _.reduce;
644
+ _.foldr = _.reduceRight;
645
+ _.select = _.filter;
646
+ _.all = _.every;
647
+ _.any = _.some;
648
+ _.head = _.first;
649
+ _.tail = _.rest;
650
+ _.methods = _.functions;
651
+
652
+ // ------------------------ Setup the OOP Wrapper: --------------------------
653
+
654
+ // If Underscore is called as a function, it returns a wrapped object that
655
+ // can be used OO-style. This wrapper holds altered versions of all the
656
+ // underscore functions. Wrapped objects may be chained.
657
+ var wrapper = function(obj) { this._wrapped = obj; };
658
+
659
+ // Helper function to continue chaining intermediate results.
660
+ var result = function(obj, chain) {
661
+ return chain ? _(obj).chain() : obj;
662
+ };
663
+
664
+ // A method to easily add functions to the OOP wrapper.
665
+ var addToWrapper = function(name, func) {
666
+ wrapper.prototype[name] = function() {
667
+ var args = _.toArray(arguments);
668
+ unshift.call(args, this._wrapped);
669
+ return result(func.apply(_, args), this._chain);
670
+ };
671
+ };
672
+
673
+ // Add all of the Underscore functions to the wrapper object.
674
+ _.mixin(_);
675
+
676
+ // Add all mutator Array functions to the wrapper.
677
+ each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
678
+ var method = ArrayProto[name];
679
+ wrapper.prototype[name] = function() {
680
+ method.apply(this._wrapped, arguments);
681
+ return result(this._wrapped, this._chain);
682
+ };
683
+ });
684
+
685
+ // Add all accessor Array functions to the wrapper.
686
+ each(['concat', 'join', 'slice'], function(name) {
687
+ var method = ArrayProto[name];
688
+ wrapper.prototype[name] = function() {
689
+ return result(method.apply(this._wrapped, arguments), this._chain);
690
+ };
691
+ });
692
+
693
+ // Start chaining a wrapped Underscore object.
694
+ wrapper.prototype.chain = function() {
695
+ this._chain = true;
696
+ return this;
697
+ };
698
+
699
+ // Extracts the result from a wrapped and chained object.
700
+ wrapper.prototype.value = function() {
701
+ return this._wrapped;
702
+ };
703
+
704
+ })();