lady_josephine 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (304) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +32 -0
  4. data/app/assets/fonts/lady_josephine/icons/icons.eot +0 -0
  5. data/app/assets/fonts/lady_josephine/icons/icons.svg +215 -0
  6. data/app/assets/fonts/lady_josephine/icons/icons.ttf +0 -0
  7. data/app/assets/fonts/lady_josephine/icons/icons.woff +0 -0
  8. data/app/assets/javascripts/lady_josephine/blocks/facebook.js +25 -0
  9. data/app/assets/javascripts/lady_josephine/blocks/instagram.js +22 -0
  10. data/app/assets/javascripts/lady_josephine/blocks/soundcloud.js +24 -0
  11. data/app/assets/javascripts/lady_josephine/blocks/twitter.js +25 -0
  12. data/app/assets/javascripts/lady_josephine/blocks/vimeo.js +55 -0
  13. data/app/assets/javascripts/lady_josephine/blocks/youtube.js +64 -0
  14. data/app/assets/javascripts/lady_josephine/editor.js +40 -0
  15. data/app/assets/javascripts/lady_josephine/lady_josephine.js +4 -0
  16. data/app/assets/javascripts/lady_josephine/lady_josephine_view.js +6 -0
  17. data/app/assets/stylesheets/lady_josephine/content.sass +33 -0
  18. data/app/assets/stylesheets/lady_josephine/icons.sass +175 -0
  19. data/app/assets/stylesheets/lady_josephine/lady_josephine.sass +6 -0
  20. data/app/assets/stylesheets/lady_josephine/sir_trevor.sass +619 -0
  21. data/app/assets/stylesheets/lady_josephine/vars.sass +36 -0
  22. data/app/controllers/lady_josephine/application_controller.rb +4 -0
  23. data/app/controllers/lady_josephine/editor_controller.rb +40 -0
  24. data/app/controllers/lady_josephine/images_controller.rb +26 -0
  25. data/app/helpers/lady_josephine/helper.rb +25 -0
  26. data/app/helpers/lady_josephine/sir_trevor_helper.rb +172 -0
  27. data/app/models/lady_josephine/concerns/model.rb +29 -0
  28. data/app/models/lady_josephine/concerns/pingable.rb +28 -0
  29. data/app/models/lady_josephine/concerns/server_uuid.rb +24 -0
  30. data/app/models/lady_josephine/concerns/sir_trevor_images.rb +38 -0
  31. data/app/models/lady_josephine/image.rb +41 -0
  32. data/app/uploader/lady_josephine/base_uploader.rb +47 -0
  33. data/app/uploader/lady_josephine/image_uploader.rb +149 -0
  34. data/app/views/lady_josephine/blocks/_audio_block.haml +2 -0
  35. data/app/views/lady_josephine/blocks/_definition_block.haml +4 -0
  36. data/app/views/lady_josephine/blocks/_divider_block.haml +2 -0
  37. data/app/views/lady_josephine/blocks/_extended_image_block.haml +63 -0
  38. data/app/views/lady_josephine/blocks/_extended_quote_block.haml +5 -0
  39. data/app/views/lady_josephine/blocks/_extended_tweet_block.haml +2 -0
  40. data/app/views/lady_josephine/blocks/_facebook_post_block.haml +2 -0
  41. data/app/views/lady_josephine/blocks/_heading_block.haml +2 -0
  42. data/app/views/lady_josephine/blocks/_html_block.haml +1 -0
  43. data/app/views/lady_josephine/blocks/_instagram_block.haml +2 -0
  44. data/app/views/lady_josephine/blocks/_list_block.haml +3 -0
  45. data/app/views/lady_josephine/blocks/_quote_block.haml +5 -0
  46. data/app/views/lady_josephine/blocks/_text_block.html.haml +2 -0
  47. data/app/views/lady_josephine/blocks/_video_block.haml +9 -0
  48. data/config/routes.rb +9 -0
  49. data/db/migrate/20160222151500_lady_josephine_image.rb +18 -0
  50. data/lib/generators/lady_josephine_migration/USAGE +9 -0
  51. data/lib/generators/lady_josephine_migration/lady_josephine_migration_generator.rb +17 -0
  52. data/lib/generators/lady_josephine_migration/templates/migration.rb +9 -0
  53. data/lib/lady_josephine.rb +18 -0
  54. data/lib/lady_josephine/engine.rb +18 -0
  55. data/lib/lady_josephine/redcarpet/custom_markdown_formatter.rb +63 -0
  56. data/lib/lady_josephine/renderer/sir_trevor_renderer.rb +16 -0
  57. data/lib/lady_josephine/version.rb +3 -0
  58. data/lib/lady_josephine/whitelist.rb +26 -0
  59. data/lib/tasks/lady_josephine_tasks.rake +4 -0
  60. data/spec/controllers/lady_josephine/editor_controller_spec.rb +58 -0
  61. data/spec/dummy/README.rdoc +28 -0
  62. data/spec/dummy/Rakefile +6 -0
  63. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  64. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  65. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  66. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  67. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  68. data/spec/dummy/bin/bundle +3 -0
  69. data/spec/dummy/bin/rails +4 -0
  70. data/spec/dummy/bin/rake +4 -0
  71. data/spec/dummy/bin/setup +29 -0
  72. data/spec/dummy/config.ru +4 -0
  73. data/spec/dummy/config/application.rb +26 -0
  74. data/spec/dummy/config/boot.rb +5 -0
  75. data/spec/dummy/config/database.yml +25 -0
  76. data/spec/dummy/config/environment.rb +5 -0
  77. data/spec/dummy/config/environments/development.rb +41 -0
  78. data/spec/dummy/config/environments/production.rb +79 -0
  79. data/spec/dummy/config/environments/test.rb +42 -0
  80. data/spec/dummy/config/initializers/assets.rb +11 -0
  81. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  82. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  83. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  84. data/spec/dummy/config/initializers/inflections.rb +16 -0
  85. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  86. data/spec/dummy/config/initializers/session_store.rb +3 -0
  87. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  88. data/spec/dummy/config/locales/en.yml +23 -0
  89. data/spec/dummy/config/routes.rb +4 -0
  90. data/spec/dummy/config/secrets.yml +22 -0
  91. data/spec/dummy/db/development.sqlite3 +0 -0
  92. data/spec/dummy/db/schema.rb +16 -0
  93. data/spec/dummy/db/test.sqlite3 +0 -0
  94. data/spec/dummy/log/bla +0 -0
  95. data/spec/dummy/public/404.html +67 -0
  96. data/spec/dummy/public/422.html +67 -0
  97. data/spec/dummy/public/500.html +66 -0
  98. data/spec/dummy/public/favicon.ico +0 -0
  99. data/spec/spec_helper.rb +17 -0
  100. data/vendor/assets/components/Eventable/README.md +12 -0
  101. data/vendor/assets/components/Eventable/bower.json +10 -0
  102. data/vendor/assets/components/Eventable/component.json +11 -0
  103. data/vendor/assets/components/Eventable/eventable.js +207 -0
  104. data/vendor/assets/components/Eventable/package.json +15 -0
  105. data/vendor/assets/components/jquery-autosize/bower.json +30 -0
  106. data/vendor/assets/components/jquery-autosize/demo.html +36 -0
  107. data/vendor/assets/components/jquery-autosize/jquery.autosize.js +273 -0
  108. data/vendor/assets/components/jquery-autosize/jquery.autosize.min.js +6 -0
  109. data/vendor/assets/components/jquery-autosize/package.json +32 -0
  110. data/vendor/assets/components/jquery-autosize/readme.md +216 -0
  111. data/vendor/assets/components/jquery/AUTHORS.txt +163 -0
  112. data/vendor/assets/components/jquery/CONTRIBUTING.md +216 -0
  113. data/vendor/assets/components/jquery/Gruntfile.js +496 -0
  114. data/vendor/assets/components/jquery/MIT-LICENSE.txt +21 -0
  115. data/vendor/assets/components/jquery/README.md +415 -0
  116. data/vendor/assets/components/jquery/build/release-notes.js +59 -0
  117. data/vendor/assets/components/jquery/build/release.js +246 -0
  118. data/vendor/assets/components/jquery/component.json +13 -0
  119. data/vendor/assets/components/jquery/composer.json +35 -0
  120. data/vendor/assets/components/jquery/jquery-migrate.js +496 -0
  121. data/vendor/assets/components/jquery/jquery-migrate.min.js +3 -0
  122. data/vendor/assets/components/jquery/jquery.js +9597 -0
  123. data/vendor/assets/components/jquery/jquery.min.js +5 -0
  124. data/vendor/assets/components/jquery/jquery.min.map +1 -0
  125. data/vendor/assets/components/jquery/package.json +39 -0
  126. data/vendor/assets/components/jquery/speed/benchmark.js +15 -0
  127. data/vendor/assets/components/jquery/speed/benchmarker.css +65 -0
  128. data/vendor/assets/components/jquery/speed/benchmarker.js +181 -0
  129. data/vendor/assets/components/jquery/speed/closest.html +39 -0
  130. data/vendor/assets/components/jquery/speed/css.html +82 -0
  131. data/vendor/assets/components/jquery/speed/event.html +58 -0
  132. data/vendor/assets/components/jquery/speed/filter.html +183 -0
  133. data/vendor/assets/components/jquery/speed/find.html +179 -0
  134. data/vendor/assets/components/jquery/speed/index.html +72 -0
  135. data/vendor/assets/components/jquery/speed/jquery-basis.js +6238 -0
  136. data/vendor/assets/components/jquery/speed/slice.vs.concat.html +47 -0
  137. data/vendor/assets/components/jquery/src/ajax.js +851 -0
  138. data/vendor/assets/components/jquery/src/ajax/jsonp.js +80 -0
  139. data/vendor/assets/components/jquery/src/ajax/script.js +86 -0
  140. data/vendor/assets/components/jquery/src/ajax/xhr.js +207 -0
  141. data/vendor/assets/components/jquery/src/attributes.js +661 -0
  142. data/vendor/assets/components/jquery/src/callbacks.js +196 -0
  143. data/vendor/assets/components/jquery/src/core.js +949 -0
  144. data/vendor/assets/components/jquery/src/css.js +679 -0
  145. data/vendor/assets/components/jquery/src/data.js +340 -0
  146. data/vendor/assets/components/jquery/src/deferred.js +141 -0
  147. data/vendor/assets/components/jquery/src/deprecated.js +4 -0
  148. data/vendor/assets/components/jquery/src/dimensions.js +41 -0
  149. data/vendor/assets/components/jquery/src/effects.js +730 -0
  150. data/vendor/assets/components/jquery/src/event-alias.js +15 -0
  151. data/vendor/assets/components/jquery/src/event.js +991 -0
  152. data/vendor/assets/components/jquery/src/exports.js +18 -0
  153. data/vendor/assets/components/jquery/src/intro.js +20 -0
  154. data/vendor/assets/components/jquery/src/manipulation.js +796 -0
  155. data/vendor/assets/components/jquery/src/offset.js +169 -0
  156. data/vendor/assets/components/jquery/src/outro.js +2 -0
  157. data/vendor/assets/components/jquery/src/queue.js +147 -0
  158. data/vendor/assets/components/jquery/src/serialize.js +99 -0
  159. data/vendor/assets/components/jquery/src/sizzle-jquery.js +9 -0
  160. data/vendor/assets/components/jquery/src/support.js +241 -0
  161. data/vendor/assets/components/jquery/src/traversing.js +275 -0
  162. data/vendor/assets/components/jquery/test/csp.php +16 -0
  163. data/vendor/assets/components/jquery/test/data/1x1.jpg +0 -0
  164. data/vendor/assets/components/jquery/test/data/ajax/unreleasedXHR.html +25 -0
  165. data/vendor/assets/components/jquery/test/data/atom+xml.php +4 -0
  166. data/vendor/assets/components/jquery/test/data/badcall.js +1 -0
  167. data/vendor/assets/components/jquery/test/data/badjson.js +1 -0
  168. data/vendor/assets/components/jquery/test/data/cleanScript.html +10 -0
  169. data/vendor/assets/components/jquery/test/data/core/cc_on.html +22 -0
  170. data/vendor/assets/components/jquery/test/data/dashboard.xml +11 -0
  171. data/vendor/assets/components/jquery/test/data/dimensions/documentLarge.html +17 -0
  172. data/vendor/assets/components/jquery/test/data/dimensions/documentSmall.html +21 -0
  173. data/vendor/assets/components/jquery/test/data/echoData.php +1 -0
  174. data/vendor/assets/components/jquery/test/data/echoQuery.php +1 -0
  175. data/vendor/assets/components/jquery/test/data/errorWithText.php +5 -0
  176. data/vendor/assets/components/jquery/test/data/etag.php +21 -0
  177. data/vendor/assets/components/jquery/test/data/evalScript.php +1 -0
  178. data/vendor/assets/components/jquery/test/data/event/longLoadScript.php +4 -0
  179. data/vendor/assets/components/jquery/test/data/event/promiseReady.html +17 -0
  180. data/vendor/assets/components/jquery/test/data/event/syncReady.html +23 -0
  181. data/vendor/assets/components/jquery/test/data/headers.php +18 -0
  182. data/vendor/assets/components/jquery/test/data/if_modified_since.php +20 -0
  183. data/vendor/assets/components/jquery/test/data/iframe.html +8 -0
  184. data/vendor/assets/components/jquery/test/data/jquery-1.8.2.ajax_xhr.min.js +2 -0
  185. data/vendor/assets/components/jquery/test/data/json.php +13 -0
  186. data/vendor/assets/components/jquery/test/data/json_obj.js +1 -0
  187. data/vendor/assets/components/jquery/test/data/jsonp.php +14 -0
  188. data/vendor/assets/components/jquery/test/data/manipulation/iframe-denied.html +36 -0
  189. data/vendor/assets/components/jquery/test/data/name.html +1 -0
  190. data/vendor/assets/components/jquery/test/data/name.php +24 -0
  191. data/vendor/assets/components/jquery/test/data/nocontent.php +5 -0
  192. data/vendor/assets/components/jquery/test/data/offset/absolute.html +41 -0
  193. data/vendor/assets/components/jquery/test/data/offset/body.html +26 -0
  194. data/vendor/assets/components/jquery/test/data/offset/fixed.html +34 -0
  195. data/vendor/assets/components/jquery/test/data/offset/relative.html +31 -0
  196. data/vendor/assets/components/jquery/test/data/offset/scroll.html +39 -0
  197. data/vendor/assets/components/jquery/test/data/offset/static.html +31 -0
  198. data/vendor/assets/components/jquery/test/data/offset/table.html +43 -0
  199. data/vendor/assets/components/jquery/test/data/params_html.php +12 -0
  200. data/vendor/assets/components/jquery/test/data/readywaitasset.js +1 -0
  201. data/vendor/assets/components/jquery/test/data/readywaitloader.js +25 -0
  202. data/vendor/assets/components/jquery/test/data/script.php +11 -0
  203. data/vendor/assets/components/jquery/test/data/selector/html5_selector.html +114 -0
  204. data/vendor/assets/components/jquery/test/data/selector/sizzle_cache.html +21 -0
  205. data/vendor/assets/components/jquery/test/data/statusText.php +5 -0
  206. data/vendor/assets/components/jquery/test/data/support/bodyBackground.html +28 -0
  207. data/vendor/assets/components/jquery/test/data/support/shrinkWrapBlocks.html +23 -0
  208. data/vendor/assets/components/jquery/test/data/support/testElementCrash.html +17 -0
  209. data/vendor/assets/components/jquery/test/data/test.html +7 -0
  210. data/vendor/assets/components/jquery/test/data/test.js +3 -0
  211. data/vendor/assets/components/jquery/test/data/test.php +7 -0
  212. data/vendor/assets/components/jquery/test/data/test2.html +5 -0
  213. data/vendor/assets/components/jquery/test/data/test3.html +3 -0
  214. data/vendor/assets/components/jquery/test/data/testinit.js +269 -0
  215. data/vendor/assets/components/jquery/test/data/testrunner.js +368 -0
  216. data/vendor/assets/components/jquery/test/data/testsuite.css +155 -0
  217. data/vendor/assets/components/jquery/test/data/text.php +12 -0
  218. data/vendor/assets/components/jquery/test/data/ua.txt +272 -0
  219. data/vendor/assets/components/jquery/test/data/with_fries.xml +25 -0
  220. data/vendor/assets/components/jquery/test/data/with_fries_over_jsonp.php +7 -0
  221. data/vendor/assets/components/jquery/test/delegatetest.html +228 -0
  222. data/vendor/assets/components/jquery/test/hovertest.html +158 -0
  223. data/vendor/assets/components/jquery/test/index.html +330 -0
  224. data/vendor/assets/components/jquery/test/localfile.html +75 -0
  225. data/vendor/assets/components/jquery/test/networkerror.html +84 -0
  226. data/vendor/assets/components/jquery/test/polluted.php +110 -0
  227. data/vendor/assets/components/jquery/test/readywait.html +70 -0
  228. data/vendor/assets/components/jquery/test/unit/ajax.js +1971 -0
  229. data/vendor/assets/components/jquery/test/unit/attributes.js +1332 -0
  230. data/vendor/assets/components/jquery/test/unit/callbacks.js +326 -0
  231. data/vendor/assets/components/jquery/test/unit/core.js +1332 -0
  232. data/vendor/assets/components/jquery/test/unit/css.js +1036 -0
  233. data/vendor/assets/components/jquery/test/unit/data.js +636 -0
  234. data/vendor/assets/components/jquery/test/unit/deferred.js +440 -0
  235. data/vendor/assets/components/jquery/test/unit/deprecated.js +1 -0
  236. data/vendor/assets/components/jquery/test/unit/dimensions.js +461 -0
  237. data/vendor/assets/components/jquery/test/unit/effects.js +2050 -0
  238. data/vendor/assets/components/jquery/test/unit/event.js +2690 -0
  239. data/vendor/assets/components/jquery/test/unit/exports.js +7 -0
  240. data/vendor/assets/components/jquery/test/unit/manipulation.js +2242 -0
  241. data/vendor/assets/components/jquery/test/unit/offset.js +549 -0
  242. data/vendor/assets/components/jquery/test/unit/queue.js +316 -0
  243. data/vendor/assets/components/jquery/test/unit/selector.js +185 -0
  244. data/vendor/assets/components/jquery/test/unit/serialize.js +146 -0
  245. data/vendor/assets/components/jquery/test/unit/support.js +384 -0
  246. data/vendor/assets/components/jquery/test/unit/traversing.js +667 -0
  247. data/vendor/assets/components/jquery/test/xhtml.php +5 -0
  248. data/vendor/assets/components/sir-trevor-js/CHANGELOG.md +44 -0
  249. data/vendor/assets/components/sir-trevor-js/Gemfile +3 -0
  250. data/vendor/assets/components/sir-trevor-js/Gemfile.lock +10 -0
  251. data/vendor/assets/components/sir-trevor-js/Gruntfile.js +109 -0
  252. data/vendor/assets/components/sir-trevor-js/MIT-LICENCE +20 -0
  253. data/vendor/assets/components/sir-trevor-js/Readme.md +84 -0
  254. data/vendor/assets/components/sir-trevor-js/bower.json +21 -0
  255. data/vendor/assets/components/sir-trevor-js/component.json +42 -0
  256. data/vendor/assets/components/sir-trevor-js/contributing.md +74 -0
  257. data/vendor/assets/components/sir-trevor-js/examples-component/component.json +14 -0
  258. data/vendor/assets/components/sir-trevor-js/examples-component/index.html +33 -0
  259. data/vendor/assets/components/sir-trevor-js/examples-component/index.js +29 -0
  260. data/vendor/assets/components/sir-trevor-js/examples-component/javascript/example_block.js +203 -0
  261. data/vendor/assets/components/sir-trevor-js/examples-component/javascript/limit_chars.js +46 -0
  262. data/vendor/assets/components/sir-trevor-js/examples-component/sir-trevor.gif +0 -0
  263. data/vendor/assets/components/sir-trevor-js/locales/cn.js +51 -0
  264. data/vendor/assets/components/sir-trevor-js/locales/de.js +51 -0
  265. data/vendor/assets/components/sir-trevor-js/locales/es.js +51 -0
  266. data/vendor/assets/components/sir-trevor-js/locales/fi.js +51 -0
  267. data/vendor/assets/components/sir-trevor-js/locales/fr.js +51 -0
  268. data/vendor/assets/components/sir-trevor-js/locales/pt.js +52 -0
  269. data/vendor/assets/components/sir-trevor-js/package.json +23 -0
  270. data/vendor/assets/components/sir-trevor-js/sir-trevor-icons.css +6 -0
  271. data/vendor/assets/components/sir-trevor-js/sir-trevor.css +393 -0
  272. data/vendor/assets/components/sir-trevor-js/sir-trevor.css.map +7 -0
  273. data/vendor/assets/components/sir-trevor-js/sir-trevor.js +5481 -0
  274. data/vendor/assets/components/sir-trevor-js/sir-trevor.min.js +13 -0
  275. data/vendor/assets/components/underscore/CNAME +1 -0
  276. data/vendor/assets/components/underscore/CONTRIBUTING.md +9 -0
  277. data/vendor/assets/components/underscore/LICENSE +22 -0
  278. data/vendor/assets/components/underscore/README.md +19 -0
  279. data/vendor/assets/components/underscore/Rakefile +10 -0
  280. data/vendor/assets/components/underscore/docs/docco.css +192 -0
  281. data/vendor/assets/components/underscore/docs/favicon.ico +0 -0
  282. data/vendor/assets/components/underscore/docs/images/background.png +0 -0
  283. data/vendor/assets/components/underscore/docs/images/underscore.png +0 -0
  284. data/vendor/assets/components/underscore/docs/underscore.html +823 -0
  285. data/vendor/assets/components/underscore/favicon.ico +0 -0
  286. data/vendor/assets/components/underscore/index.html +2467 -0
  287. data/vendor/assets/components/underscore/index.js +1 -0
  288. data/vendor/assets/components/underscore/package.json +16 -0
  289. data/vendor/assets/components/underscore/test/arrays.js +200 -0
  290. data/vendor/assets/components/underscore/test/chaining.js +59 -0
  291. data/vendor/assets/components/underscore/test/collections.js +453 -0
  292. data/vendor/assets/components/underscore/test/functions.js +265 -0
  293. data/vendor/assets/components/underscore/test/index.html +44 -0
  294. data/vendor/assets/components/underscore/test/objects.js +570 -0
  295. data/vendor/assets/components/underscore/test/speed.js +75 -0
  296. data/vendor/assets/components/underscore/test/utility.js +266 -0
  297. data/vendor/assets/components/underscore/test/vendor/jquery.js +9404 -0
  298. data/vendor/assets/components/underscore/test/vendor/jslitmus.js +670 -0
  299. data/vendor/assets/components/underscore/test/vendor/qunit.css +235 -0
  300. data/vendor/assets/components/underscore/test/vendor/qunit.js +1977 -0
  301. data/vendor/assets/components/underscore/test/vendor/runner.js +98 -0
  302. data/vendor/assets/components/underscore/underscore-min.js +1 -0
  303. data/vendor/assets/components/underscore/underscore.js +1226 -0
  304. metadata +473 -0
@@ -0,0 +1,265 @@
1
+ $(document).ready(function() {
2
+
3
+ module("Functions");
4
+
5
+ test("bind", function() {
6
+ var context = {name : 'moe'};
7
+ var func = function(arg) { return "name: " + (this.name || arg); };
8
+ var bound = _.bind(func, context);
9
+ equal(bound(), 'name: moe', 'can bind a function to a context');
10
+
11
+ bound = _(func).bind(context);
12
+ equal(bound(), 'name: moe', 'can do OO-style binding');
13
+
14
+ bound = _.bind(func, null, 'curly');
15
+ equal(bound(), 'name: curly', 'can bind without specifying a context');
16
+
17
+ func = function(salutation, name) { return salutation + ': ' + name; };
18
+ func = _.bind(func, this, 'hello');
19
+ equal(func('moe'), 'hello: moe', 'the function was partially applied in advance');
20
+
21
+ func = _.bind(func, this, 'curly');
22
+ equal(func(), 'hello: curly', 'the function was completely applied in advance');
23
+
24
+ func = function(salutation, firstname, lastname) { return salutation + ': ' + firstname + ' ' + lastname; };
25
+ func = _.bind(func, this, 'hello', 'moe', 'curly');
26
+ equal(func(), 'hello: moe curly', 'the function was partially applied in advance and can accept multiple arguments');
27
+
28
+ func = function(context, message) { equal(this, context, message); };
29
+ _.bind(func, 0, 0, 'can bind a function to `0`')();
30
+ _.bind(func, '', '', 'can bind a function to an empty string')();
31
+ _.bind(func, false, false, 'can bind a function to `false`')();
32
+
33
+ // These tests are only meaningful when using a browser without a native bind function
34
+ // To test this with a modern browser, set underscore's nativeBind to undefined
35
+ var F = function () { return this; };
36
+ var Boundf = _.bind(F, {hello: "moe curly"});
37
+ equal(Boundf().hello, "moe curly", "When called without the new operator, it's OK to be bound to the context");
38
+ });
39
+
40
+ test("partial", function() {
41
+ var obj = {name: 'moe'};
42
+ var func = function() { return this.name + ' ' + _.toArray(arguments).join(' '); };
43
+
44
+ obj.func = _.partial(func, 'a', 'b');
45
+ equal(obj.func('c', 'd'), 'moe a b c d', 'can partially apply');
46
+ });
47
+
48
+ test("bindAll", function() {
49
+ var curly = {name : 'curly'}, moe = {
50
+ name : 'moe',
51
+ getName : function() { return 'name: ' + this.name; },
52
+ sayHi : function() { return 'hi: ' + this.name; }
53
+ };
54
+ curly.getName = moe.getName;
55
+ _.bindAll(moe, 'getName', 'sayHi');
56
+ curly.sayHi = moe.sayHi;
57
+ equal(curly.getName(), 'name: curly', 'unbound function is bound to current object');
58
+ equal(curly.sayHi(), 'hi: moe', 'bound function is still bound to original object');
59
+
60
+ curly = {name : 'curly'};
61
+ moe = {
62
+ name : 'moe',
63
+ getName : function() { return 'name: ' + this.name; },
64
+ sayHi : function() { return 'hi: ' + this.name; }
65
+ };
66
+ _.bindAll(moe);
67
+ curly.sayHi = moe.sayHi;
68
+ equal(curly.sayHi(), 'hi: moe', 'calling bindAll with no arguments binds all functions to the object');
69
+ });
70
+
71
+ test("memoize", function() {
72
+ var fib = function(n) {
73
+ return n < 2 ? n : fib(n - 1) + fib(n - 2);
74
+ };
75
+ var fastFib = _.memoize(fib);
76
+ equal(fib(10), 55, 'a memoized version of fibonacci produces identical results');
77
+ equal(fastFib(10), 55, 'a memoized version of fibonacci produces identical results');
78
+
79
+ var o = function(str) {
80
+ return str;
81
+ };
82
+ var fastO = _.memoize(o);
83
+ equal(o('toString'), 'toString', 'checks hasOwnProperty');
84
+ equal(fastO('toString'), 'toString', 'checks hasOwnProperty');
85
+ });
86
+
87
+ asyncTest("delay", 2, function() {
88
+ var delayed = false;
89
+ _.delay(function(){ delayed = true; }, 100);
90
+ setTimeout(function(){ ok(!delayed, "didn't delay the function quite yet"); }, 50);
91
+ setTimeout(function(){ ok(delayed, 'delayed the function'); start(); }, 150);
92
+ });
93
+
94
+ asyncTest("defer", 1, function() {
95
+ var deferred = false;
96
+ _.defer(function(bool){ deferred = bool; }, true);
97
+ _.delay(function(){ ok(deferred, "deferred the function"); start(); }, 50);
98
+ });
99
+
100
+ asyncTest("throttle", 2, function() {
101
+ var counter = 0;
102
+ var incr = function(){ counter++; };
103
+ var throttledIncr = _.throttle(incr, 32);
104
+ throttledIncr(); throttledIncr();
105
+
106
+ equal(counter, 1, "incr was called immediately");
107
+ _.delay(function(){ equal(counter, 2, "incr was throttled"); start(); }, 64);
108
+ });
109
+
110
+ asyncTest("throttle arguments", 2, function() {
111
+ var value = 0;
112
+ var update = function(val){ value = val; };
113
+ var throttledUpdate = _.throttle(update, 32);
114
+ throttledUpdate(1); throttledUpdate(2);
115
+ _.delay(function(){ throttledUpdate(3); }, 64);
116
+ equal(value, 1, "updated to latest value");
117
+ _.delay(function(){ equal(value, 3, "updated to latest value"); start(); }, 96);
118
+ });
119
+
120
+ asyncTest("throttle once", 2, function() {
121
+ var counter = 0;
122
+ var incr = function(){ return ++counter; };
123
+ var throttledIncr = _.throttle(incr, 32);
124
+ var result = throttledIncr();
125
+ _.delay(function(){
126
+ equal(result, 1, "throttled functions return their value");
127
+ equal(counter, 1, "incr was called once"); start();
128
+ }, 64);
129
+ });
130
+
131
+ asyncTest("throttle twice", 1, function() {
132
+ var counter = 0;
133
+ var incr = function(){ counter++; };
134
+ var throttledIncr = _.throttle(incr, 32);
135
+ throttledIncr(); throttledIncr();
136
+ _.delay(function(){ equal(counter, 2, "incr was called twice"); start(); }, 64);
137
+ });
138
+
139
+ asyncTest("throttle repeatedly with results", 6, function() {
140
+ var counter = 0;
141
+ var incr = function(){ return ++counter; };
142
+ var throttledIncr = _.throttle(incr, 64);
143
+ var results = [];
144
+ var saveResult = function() { results.push(throttledIncr()); };
145
+ saveResult(); saveResult();
146
+ _.delay(saveResult, 32);
147
+ _.delay(saveResult, 80);
148
+ _.delay(saveResult, 96);
149
+ _.delay(saveResult, 144);
150
+ _.delay(function() {
151
+ equal(results[0], 1, "incr was called once");
152
+ equal(results[1], 1, "incr was throttled");
153
+ equal(results[2], 1, "incr was throttled");
154
+ equal(results[3], 2, "incr was called twice");
155
+ equal(results[4], 2, "incr was throttled");
156
+ equal(results[5], 3, "incr was called trailing");
157
+ start();
158
+ }, 192);
159
+ });
160
+
161
+ asyncTest("throttle triggers trailing call when invoked repeatedly", 2, function() {
162
+ var counter = 0;
163
+ var limit = 48;
164
+ var incr = function(){ counter++; };
165
+ var throttledIncr = _.throttle(incr, 32);
166
+
167
+ var stamp = new Date;
168
+ while ((new Date - stamp) < limit) {
169
+ throttledIncr();
170
+ }
171
+ var lastCount = counter;
172
+ ok(counter > 1);
173
+
174
+ _.delay(function() {
175
+ ok(counter > lastCount);
176
+ start();
177
+ }, 96);
178
+ });
179
+
180
+ asyncTest("debounce", 1, function() {
181
+ var counter = 0;
182
+ var incr = function(){ counter++; };
183
+ var debouncedIncr = _.debounce(incr, 32);
184
+ debouncedIncr(); debouncedIncr();
185
+ _.delay(debouncedIncr, 16);
186
+ _.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 96);
187
+ });
188
+
189
+ asyncTest("debounce asap", 4, function() {
190
+ var a, b;
191
+ var counter = 0;
192
+ var incr = function(){ return ++counter; };
193
+ var debouncedIncr = _.debounce(incr, 64, true);
194
+ a = debouncedIncr();
195
+ b = debouncedIncr();
196
+ equal(a, 1);
197
+ equal(b, 1);
198
+ equal(counter, 1, 'incr was called immediately');
199
+ _.delay(debouncedIncr, 16);
200
+ _.delay(debouncedIncr, 32);
201
+ _.delay(debouncedIncr, 48);
202
+ _.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 128);
203
+ });
204
+
205
+ asyncTest("debounce asap recursively", 2, function() {
206
+ var counter = 0;
207
+ var debouncedIncr = _.debounce(function(){
208
+ counter++;
209
+ if (counter < 10) debouncedIncr();
210
+ }, 32, true);
211
+ debouncedIncr();
212
+ equal(counter, 1, "incr was called immediately");
213
+ _.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 96);
214
+ });
215
+
216
+ test("once", function() {
217
+ var num = 0;
218
+ var increment = _.once(function(){ num++; });
219
+ increment();
220
+ increment();
221
+ equal(num, 1);
222
+ });
223
+
224
+ test("wrap", function() {
225
+ var greet = function(name){ return "hi: " + name; };
226
+ var backwards = _.wrap(greet, function(func, name){ return func(name) + ' ' + name.split('').reverse().join(''); });
227
+ equal(backwards('moe'), 'hi: moe eom', 'wrapped the saluation function');
228
+
229
+ var inner = function(){ return "Hello "; };
230
+ var obj = {name : "Moe"};
231
+ obj.hi = _.wrap(inner, function(fn){ return fn() + this.name; });
232
+ equal(obj.hi(), "Hello Moe");
233
+
234
+ var noop = function(){};
235
+ var wrapped = _.wrap(noop, function(fn){ return Array.prototype.slice.call(arguments, 0); });
236
+ var ret = wrapped(['whats', 'your'], 'vector', 'victor');
237
+ deepEqual(ret, [noop, ['whats', 'your'], 'vector', 'victor']);
238
+ });
239
+
240
+ test("compose", function() {
241
+ var greet = function(name){ return "hi: " + name; };
242
+ var exclaim = function(sentence){ return sentence + '!'; };
243
+ var composed = _.compose(exclaim, greet);
244
+ equal(composed('moe'), 'hi: moe!', 'can compose a function that takes another');
245
+
246
+ composed = _.compose(greet, exclaim);
247
+ equal(composed('moe'), 'hi: moe!', 'in this case, the functions are also commutative');
248
+ });
249
+
250
+ test("after", function() {
251
+ var testAfter = function(afterAmount, timesCalled) {
252
+ var afterCalled = 0;
253
+ var after = _.after(afterAmount, function() {
254
+ afterCalled++;
255
+ });
256
+ while (timesCalled--) after();
257
+ return afterCalled;
258
+ };
259
+
260
+ equal(testAfter(5, 5), 1, "after(N) should fire after being called N times");
261
+ equal(testAfter(5, 4), 0, "after(N) should not fire unless called N times");
262
+ equal(testAfter(0, 0), 1, "after(0) should fire immediately");
263
+ });
264
+
265
+ });
@@ -0,0 +1,44 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Underscore Test Suite</title>
5
+ <link rel="stylesheet" href="vendor/qunit.css" type="text/css" media="screen">
6
+ <script src="vendor/jquery.js"></script>
7
+ <script src="vendor/qunit.js"></script>
8
+ <script src="vendor/jslitmus.js"></script>
9
+ <script src="../underscore.js"></script>
10
+
11
+ <script src="collections.js"></script>
12
+ <script src="arrays.js"></script>
13
+ <script src="functions.js"></script>
14
+ <script src="objects.js"></script>
15
+ <script src="utility.js"></script>
16
+ <script src="chaining.js"></script>
17
+ <script src="speed.js"></script>
18
+ </head>
19
+ <body>
20
+ <div id="qunit"></div>
21
+ <div id="qunit-fixture">
22
+ <div id="map-test">
23
+ <div id="id1"></div>
24
+ <div id="id2"></div>
25
+ </div>
26
+ </div>
27
+ <br>
28
+ <h1 class="qunit-header">Underscore Speed Suite</h1>
29
+ <p>
30
+ A representative sample of the functions are benchmarked here, to provide
31
+ a sense of how fast they might run in different browsers.
32
+ Each iteration runs on an array of 1000 elements.<br /><br />
33
+ For example, the 'intersection' test measures the number of times you can
34
+ find the intersection of two thousand-element arrays in one second.
35
+ </p>
36
+ <br>
37
+ <script type="text/html" id="template">
38
+ <%
39
+ // a comment
40
+ if (data) { data += 12345; }; %>
41
+ <li><%= data %></li>
42
+ </script>
43
+ </body>
44
+ </html>
@@ -0,0 +1,570 @@
1
+ $(document).ready(function() {
2
+
3
+ module("Objects");
4
+
5
+ test("keys", function() {
6
+ equal(_.keys({one : 1, two : 2}).join(', '), 'one, two', 'can extract the keys from an object');
7
+ // the test above is not safe because it relies on for-in enumeration order
8
+ var a = []; a[1] = 0;
9
+ equal(_.keys(a).join(', '), '1', 'is not fooled by sparse arrays; see issue #95');
10
+ raises(function() { _.keys(null); }, TypeError, 'throws an error for `null` values');
11
+ raises(function() { _.keys(void 0); }, TypeError, 'throws an error for `undefined` values');
12
+ raises(function() { _.keys(1); }, TypeError, 'throws an error for number primitives');
13
+ raises(function() { _.keys('a'); }, TypeError, 'throws an error for string primitives');
14
+ raises(function() { _.keys(true); }, TypeError, 'throws an error for boolean primitives');
15
+ });
16
+
17
+ test("values", function() {
18
+ equal(_.values({one: 1, two: 2}).join(', '), '1, 2', 'can extract the values from an object');
19
+ equal(_.values({one: 1, two: 2, length: 3}).join(', '), '1, 2, 3', '... even when one of them is "length"');
20
+ });
21
+
22
+ test("pairs", function() {
23
+ deepEqual(_.pairs({one: 1, two: 2}), [['one', 1], ['two', 2]], 'can convert an object into pairs');
24
+ deepEqual(_.pairs({one: 1, two: 2, length: 3}), [['one', 1], ['two', 2], ['length', 3]], '... even when one of them is "length"');
25
+ });
26
+
27
+ test("invert", function() {
28
+ var obj = {first: 'Moe', second: 'Larry', third: 'Curly'};
29
+ equal(_.keys(_.invert(obj)).join(' '), 'Moe Larry Curly', 'can invert an object');
30
+ ok(_.isEqual(_.invert(_.invert(obj)), obj), 'two inverts gets you back where you started');
31
+
32
+ var obj = {length: 3};
33
+ ok(_.invert(obj)['3'] == 'length', 'can invert an object with "length"')
34
+ });
35
+
36
+ test("functions", function() {
37
+ var obj = {a : 'dash', b : _.map, c : (/yo/), d : _.reduce};
38
+ ok(_.isEqual(['b', 'd'], _.functions(obj)), 'can grab the function names of any passed-in object');
39
+
40
+ var Animal = function(){};
41
+ Animal.prototype.run = function(){};
42
+ equal(_.functions(new Animal).join(''), 'run', 'also looks up functions on the prototype');
43
+ });
44
+
45
+ test("extend", function() {
46
+ var result;
47
+ equal(_.extend({}, {a:'b'}).a, 'b', 'can extend an object with the attributes of another');
48
+ equal(_.extend({a:'x'}, {a:'b'}).a, 'b', 'properties in source override destination');
49
+ equal(_.extend({x:'x'}, {a:'b'}).x, 'x', 'properties not in source dont get overriden');
50
+ result = _.extend({x:'x'}, {a:'a'}, {b:'b'});
51
+ ok(_.isEqual(result, {x:'x', a:'a', b:'b'}), 'can extend from multiple source objects');
52
+ result = _.extend({x:'x'}, {a:'a', x:2}, {a:'b'});
53
+ ok(_.isEqual(result, {x:2, a:'b'}), 'extending from multiple source objects last property trumps');
54
+ result = _.extend({}, {a: void 0, b: null});
55
+ equal(_.keys(result).join(''), 'ab', 'extend does not copy undefined values');
56
+
57
+ try {
58
+ result = {};
59
+ _.extend(result, null, undefined, {a:1});
60
+ } catch(ex) {}
61
+
62
+ equal(result.a, 1, 'should not error on `null` or `undefined` sources');
63
+ });
64
+
65
+ test("pick", function() {
66
+ var result;
67
+ result = _.pick({a:1, b:2, c:3}, 'a', 'c');
68
+ ok(_.isEqual(result, {a:1, c:3}), 'can restrict properties to those named');
69
+ result = _.pick({a:1, b:2, c:3}, ['b', 'c']);
70
+ ok(_.isEqual(result, {b:2, c:3}), 'can restrict properties to those named in an array');
71
+ result = _.pick({a:1, b:2, c:3}, ['a'], 'b');
72
+ ok(_.isEqual(result, {a:1, b:2}), 'can restrict properties to those named in mixed args');
73
+
74
+ var Obj = function(){};
75
+ Obj.prototype = {a: 1, b: 2, c: 3};
76
+ ok(_.isEqual(_.pick(new Obj, 'a', 'c'), {a:1, c: 3}), 'include prototype props');
77
+ });
78
+
79
+ test("omit", function() {
80
+ var result;
81
+ result = _.omit({a:1, b:2, c:3}, 'b');
82
+ ok(_.isEqual(result, {a:1, c:3}), 'can omit a single named property');
83
+ result = _.omit({a:1, b:2, c:3}, 'a', 'c');
84
+ ok(_.isEqual(result, {b:2}), 'can omit several named properties');
85
+ result = _.omit({a:1, b:2, c:3}, ['b', 'c']);
86
+ ok(_.isEqual(result, {a:1}), 'can omit properties named in an array');
87
+
88
+ var Obj = function(){};
89
+ Obj.prototype = {a: 1, b: 2, c: 3};
90
+ ok(_.isEqual(_.omit(new Obj, 'b'), {a:1, c: 3}), 'include prototype props');
91
+ });
92
+
93
+ test("defaults", function() {
94
+ var result;
95
+ var options = {zero: 0, one: 1, empty: "", nan: NaN, string: "string"};
96
+
97
+ _.defaults(options, {zero: 1, one: 10, twenty: 20});
98
+ equal(options.zero, 0, 'value exists');
99
+ equal(options.one, 1, 'value exists');
100
+ equal(options.twenty, 20, 'default applied');
101
+
102
+ _.defaults(options, {empty: "full"}, {nan: "nan"}, {word: "word"}, {word: "dog"});
103
+ equal(options.empty, "", 'value exists');
104
+ ok(_.isNaN(options.nan), "NaN isn't overridden");
105
+ equal(options.word, "word", 'new value is added, first one wins');
106
+
107
+ try {
108
+ options = {};
109
+ _.defaults(options, null, undefined, {a:1});
110
+ } catch(ex) {}
111
+
112
+ equal(options.a, 1, 'should not error on `null` or `undefined` sources');
113
+ });
114
+
115
+ test("clone", function() {
116
+ var moe = {name : 'moe', lucky : [13, 27, 34]};
117
+ var clone = _.clone(moe);
118
+ equal(clone.name, 'moe', 'the clone as the attributes of the original');
119
+
120
+ clone.name = 'curly';
121
+ ok(clone.name == 'curly' && moe.name == 'moe', 'clones can change shallow attributes without affecting the original');
122
+
123
+ clone.lucky.push(101);
124
+ equal(_.last(moe.lucky), 101, 'changes to deep attributes are shared with the original');
125
+
126
+ equal(_.clone(undefined), void 0, 'non objects should not be changed by clone');
127
+ equal(_.clone(1), 1, 'non objects should not be changed by clone');
128
+ equal(_.clone(null), null, 'non objects should not be changed by clone');
129
+ });
130
+
131
+ test("isEqual", function() {
132
+ function First() {
133
+ this.value = 1;
134
+ }
135
+ First.prototype.value = 1;
136
+ function Second() {
137
+ this.value = 1;
138
+ }
139
+ Second.prototype.value = 2;
140
+
141
+ // Basic equality and identity comparisons.
142
+ ok(_.isEqual(null, null), "`null` is equal to `null`");
143
+ ok(_.isEqual(), "`undefined` is equal to `undefined`");
144
+
145
+ ok(!_.isEqual(0, -0), "`0` is not equal to `-0`");
146
+ ok(!_.isEqual(-0, 0), "Commutative equality is implemented for `0` and `-0`");
147
+ ok(!_.isEqual(null, undefined), "`null` is not equal to `undefined`");
148
+ ok(!_.isEqual(undefined, null), "Commutative equality is implemented for `null` and `undefined`");
149
+
150
+ // String object and primitive comparisons.
151
+ ok(_.isEqual("Curly", "Curly"), "Identical string primitives are equal");
152
+ ok(_.isEqual(new String("Curly"), new String("Curly")), "String objects with identical primitive values are equal");
153
+ ok(_.isEqual(new String("Curly"), "Curly"), "String primitives and their corresponding object wrappers are equal");
154
+ ok(_.isEqual("Curly", new String("Curly")), "Commutative equality is implemented for string objects and primitives");
155
+
156
+ ok(!_.isEqual("Curly", "Larry"), "String primitives with different values are not equal");
157
+ ok(!_.isEqual(new String("Curly"), new String("Larry")), "String objects with different primitive values are not equal");
158
+ ok(!_.isEqual(new String("Curly"), {toString: function(){ return "Curly"; }}), "String objects and objects with a custom `toString` method are not equal");
159
+
160
+ // Number object and primitive comparisons.
161
+ ok(_.isEqual(75, 75), "Identical number primitives are equal");
162
+ ok(_.isEqual(new Number(75), new Number(75)), "Number objects with identical primitive values are equal");
163
+ ok(_.isEqual(75, new Number(75)), "Number primitives and their corresponding object wrappers are equal");
164
+ ok(_.isEqual(new Number(75), 75), "Commutative equality is implemented for number objects and primitives");
165
+ ok(!_.isEqual(new Number(0), -0), "`new Number(0)` and `-0` are not equal");
166
+ ok(!_.isEqual(0, new Number(-0)), "Commutative equality is implemented for `new Number(0)` and `-0`");
167
+
168
+ ok(!_.isEqual(new Number(75), new Number(63)), "Number objects with different primitive values are not equal");
169
+ ok(!_.isEqual(new Number(63), {valueOf: function(){ return 63; }}), "Number objects and objects with a `valueOf` method are not equal");
170
+
171
+ // Comparisons involving `NaN`.
172
+ ok(_.isEqual(NaN, NaN), "`NaN` is equal to `NaN`");
173
+ ok(!_.isEqual(61, NaN), "A number primitive is not equal to `NaN`");
174
+ ok(!_.isEqual(new Number(79), NaN), "A number object is not equal to `NaN`");
175
+ ok(!_.isEqual(Infinity, NaN), "`Infinity` is not equal to `NaN`");
176
+
177
+ // Boolean object and primitive comparisons.
178
+ ok(_.isEqual(true, true), "Identical boolean primitives are equal");
179
+ ok(_.isEqual(new Boolean, new Boolean), "Boolean objects with identical primitive values are equal");
180
+ ok(_.isEqual(true, new Boolean(true)), "Boolean primitives and their corresponding object wrappers are equal");
181
+ ok(_.isEqual(new Boolean(true), true), "Commutative equality is implemented for booleans");
182
+ ok(!_.isEqual(new Boolean(true), new Boolean), "Boolean objects with different primitive values are not equal");
183
+
184
+ // Common type coercions.
185
+ ok(!_.isEqual(true, new Boolean(false)), "Boolean objects are not equal to the boolean primitive `true`");
186
+ ok(!_.isEqual("75", 75), "String and number primitives with like values are not equal");
187
+ ok(!_.isEqual(new Number(63), new String(63)), "String and number objects with like values are not equal");
188
+ ok(!_.isEqual(75, "75"), "Commutative equality is implemented for like string and number values");
189
+ ok(!_.isEqual(0, ""), "Number and string primitives with like values are not equal");
190
+ ok(!_.isEqual(1, true), "Number and boolean primitives with like values are not equal");
191
+ ok(!_.isEqual(new Boolean(false), new Number(0)), "Boolean and number objects with like values are not equal");
192
+ ok(!_.isEqual(false, new String("")), "Boolean primitives and string objects with like values are not equal");
193
+ ok(!_.isEqual(12564504e5, new Date(2009, 9, 25)), "Dates and their corresponding numeric primitive values are not equal");
194
+
195
+ // Dates.
196
+ ok(_.isEqual(new Date(2009, 9, 25), new Date(2009, 9, 25)), "Date objects referencing identical times are equal");
197
+ ok(!_.isEqual(new Date(2009, 9, 25), new Date(2009, 11, 13)), "Date objects referencing different times are not equal");
198
+ ok(!_.isEqual(new Date(2009, 11, 13), {
199
+ getTime: function(){
200
+ return 12606876e5;
201
+ }
202
+ }), "Date objects and objects with a `getTime` method are not equal");
203
+ ok(!_.isEqual(new Date("Curly"), new Date("Curly")), "Invalid dates are not equal");
204
+
205
+ // Functions.
206
+ ok(!_.isEqual(First, Second), "Different functions with identical bodies and source code representations are not equal");
207
+
208
+ // RegExps.
209
+ ok(_.isEqual(/(?:)/gim, /(?:)/gim), "RegExps with equivalent patterns and flags are equal");
210
+ ok(!_.isEqual(/(?:)/g, /(?:)/gi), "RegExps with equivalent patterns and different flags are not equal");
211
+ ok(!_.isEqual(/Moe/gim, /Curly/gim), "RegExps with different patterns and equivalent flags are not equal");
212
+ ok(!_.isEqual(/(?:)/gi, /(?:)/g), "Commutative equality is implemented for RegExps");
213
+ ok(!_.isEqual(/Curly/g, {source: "Larry", global: true, ignoreCase: false, multiline: false}), "RegExps and RegExp-like objects are not equal");
214
+
215
+ // Empty arrays, array-like objects, and object literals.
216
+ ok(_.isEqual({}, {}), "Empty object literals are equal");
217
+ ok(_.isEqual([], []), "Empty array literals are equal");
218
+ ok(_.isEqual([{}], [{}]), "Empty nested arrays and objects are equal");
219
+ ok(!_.isEqual({length: 0}, []), "Array-like objects and arrays are not equal.");
220
+ ok(!_.isEqual([], {length: 0}), "Commutative equality is implemented for array-like objects");
221
+
222
+ ok(!_.isEqual({}, []), "Object literals and array literals are not equal");
223
+ ok(!_.isEqual([], {}), "Commutative equality is implemented for objects and arrays");
224
+
225
+ // Arrays with primitive and object values.
226
+ ok(_.isEqual([1, "Larry", true], [1, "Larry", true]), "Arrays containing identical primitives are equal");
227
+ ok(_.isEqual([(/Moe/g), new Date(2009, 9, 25)], [(/Moe/g), new Date(2009, 9, 25)]), "Arrays containing equivalent elements are equal");
228
+
229
+ // Multi-dimensional arrays.
230
+ var a = [new Number(47), false, "Larry", /Moe/, new Date(2009, 11, 13), ['running', 'biking', new String('programming')], {a: 47}];
231
+ var b = [new Number(47), false, "Larry", /Moe/, new Date(2009, 11, 13), ['running', 'biking', new String('programming')], {a: 47}];
232
+ ok(_.isEqual(a, b), "Arrays containing nested arrays and objects are recursively compared");
233
+
234
+ // Overwrite the methods defined in ES 5.1 section 15.4.4.
235
+ a.forEach = a.map = a.filter = a.every = a.indexOf = a.lastIndexOf = a.some = a.reduce = a.reduceRight = null;
236
+ b.join = b.pop = b.reverse = b.shift = b.slice = b.splice = b.concat = b.sort = b.unshift = null;
237
+
238
+ // Array elements and properties.
239
+ ok(_.isEqual(a, b), "Arrays containing equivalent elements and different non-numeric properties are equal");
240
+ a.push("White Rocks");
241
+ ok(!_.isEqual(a, b), "Arrays of different lengths are not equal");
242
+ a.push("East Boulder");
243
+ b.push("Gunbarrel Ranch", "Teller Farm");
244
+ ok(!_.isEqual(a, b), "Arrays of identical lengths containing different elements are not equal");
245
+
246
+ // Sparse arrays.
247
+ ok(_.isEqual(Array(3), Array(3)), "Sparse arrays of identical lengths are equal");
248
+ ok(!_.isEqual(Array(3), Array(6)), "Sparse arrays of different lengths are not equal when both are empty");
249
+
250
+ // Simple objects.
251
+ ok(_.isEqual({a: "Curly", b: 1, c: true}, {a: "Curly", b: 1, c: true}), "Objects containing identical primitives are equal");
252
+ ok(_.isEqual({a: /Curly/g, b: new Date(2009, 11, 13)}, {a: /Curly/g, b: new Date(2009, 11, 13)}), "Objects containing equivalent members are equal");
253
+ ok(!_.isEqual({a: 63, b: 75}, {a: 61, b: 55}), "Objects of identical sizes with different values are not equal");
254
+ ok(!_.isEqual({a: 63, b: 75}, {a: 61, c: 55}), "Objects of identical sizes with different property names are not equal");
255
+ ok(!_.isEqual({a: 1, b: 2}, {a: 1}), "Objects of different sizes are not equal");
256
+ ok(!_.isEqual({a: 1}, {a: 1, b: 2}), "Commutative equality is implemented for objects");
257
+ ok(!_.isEqual({x: 1, y: undefined}, {x: 1, z: 2}), "Objects with identical keys and different values are not equivalent");
258
+
259
+ // `A` contains nested objects and arrays.
260
+ a = {
261
+ name: new String("Moe Howard"),
262
+ age: new Number(77),
263
+ stooge: true,
264
+ hobbies: ["acting"],
265
+ film: {
266
+ name: "Sing a Song of Six Pants",
267
+ release: new Date(1947, 9, 30),
268
+ stars: [new String("Larry Fine"), "Shemp Howard"],
269
+ minutes: new Number(16),
270
+ seconds: 54
271
+ }
272
+ };
273
+
274
+ // `B` contains equivalent nested objects and arrays.
275
+ b = {
276
+ name: new String("Moe Howard"),
277
+ age: new Number(77),
278
+ stooge: true,
279
+ hobbies: ["acting"],
280
+ film: {
281
+ name: "Sing a Song of Six Pants",
282
+ release: new Date(1947, 9, 30),
283
+ stars: [new String("Larry Fine"), "Shemp Howard"],
284
+ minutes: new Number(16),
285
+ seconds: 54
286
+ }
287
+ };
288
+ ok(_.isEqual(a, b), "Objects with nested equivalent members are recursively compared");
289
+
290
+ // Instances.
291
+ ok(_.isEqual(new First, new First), "Object instances are equal");
292
+ ok(!_.isEqual(new First, new Second), "Objects with different constructors and identical own properties are not equal");
293
+ ok(!_.isEqual({value: 1}, new First), "Object instances and objects sharing equivalent properties are not equal");
294
+ ok(!_.isEqual({value: 2}, new Second), "The prototype chain of objects should not be examined");
295
+
296
+ // Circular Arrays.
297
+ (a = []).push(a);
298
+ (b = []).push(b);
299
+ ok(_.isEqual(a, b), "Arrays containing circular references are equal");
300
+ a.push(new String("Larry"));
301
+ b.push(new String("Larry"));
302
+ ok(_.isEqual(a, b), "Arrays containing circular references and equivalent properties are equal");
303
+ a.push("Shemp");
304
+ b.push("Curly");
305
+ ok(!_.isEqual(a, b), "Arrays containing circular references and different properties are not equal");
306
+
307
+ // More circular arrays #767.
308
+ a = ["everything is checked but", "this", "is not"];
309
+ a[1] = a;
310
+ b = ["everything is checked but", ["this", "array"], "is not"];
311
+ ok(!_.isEqual(a, b), "Comparison of circular references with non-circular references are not equal");
312
+
313
+ // Circular Objects.
314
+ a = {abc: null};
315
+ b = {abc: null};
316
+ a.abc = a;
317
+ b.abc = b;
318
+ ok(_.isEqual(a, b), "Objects containing circular references are equal");
319
+ a.def = 75;
320
+ b.def = 75;
321
+ ok(_.isEqual(a, b), "Objects containing circular references and equivalent properties are equal");
322
+ a.def = new Number(75);
323
+ b.def = new Number(63);
324
+ ok(!_.isEqual(a, b), "Objects containing circular references and different properties are not equal");
325
+
326
+ // More circular objects #767.
327
+ a = {everything: "is checked", but: "this", is: "not"};
328
+ a.but = a;
329
+ b = {everything: "is checked", but: {that:"object"}, is: "not"};
330
+ ok(!_.isEqual(a, b), "Comparison of circular references with non-circular object references are not equal");
331
+
332
+ // Cyclic Structures.
333
+ a = [{abc: null}];
334
+ b = [{abc: null}];
335
+ (a[0].abc = a).push(a);
336
+ (b[0].abc = b).push(b);
337
+ ok(_.isEqual(a, b), "Cyclic structures are equal");
338
+ a[0].def = "Larry";
339
+ b[0].def = "Larry";
340
+ ok(_.isEqual(a, b), "Cyclic structures containing equivalent properties are equal");
341
+ a[0].def = new String("Larry");
342
+ b[0].def = new String("Curly");
343
+ ok(!_.isEqual(a, b), "Cyclic structures containing different properties are not equal");
344
+
345
+ // Complex Circular References.
346
+ a = {foo: {b: {foo: {c: {foo: null}}}}};
347
+ b = {foo: {b: {foo: {c: {foo: null}}}}};
348
+ a.foo.b.foo.c.foo = a;
349
+ b.foo.b.foo.c.foo = b;
350
+ ok(_.isEqual(a, b), "Cyclic structures with nested and identically-named properties are equal");
351
+
352
+ // Chaining.
353
+ ok(!_.isEqual(_({x: 1, y: undefined}).chain(), _({x: 1, z: 2}).chain()), 'Chained objects containing different values are not equal');
354
+
355
+ a = _({x: 1, y: 2}).chain();
356
+ b = _({x: 1, y: 2}).chain();
357
+ equal(_.isEqual(a.isEqual(b), _(true)), true, '`isEqual` can be chained');
358
+
359
+ // Objects from another frame.
360
+ ok(_.isEqual({}, iObject));
361
+ });
362
+
363
+ test("isEmpty", function() {
364
+ ok(!_([1]).isEmpty(), '[1] is not empty');
365
+ ok(_.isEmpty([]), '[] is empty');
366
+ ok(!_.isEmpty({one : 1}), '{one : 1} is not empty');
367
+ ok(_.isEmpty({}), '{} is empty');
368
+ ok(_.isEmpty(new RegExp('')), 'objects with prototype properties are empty');
369
+ ok(_.isEmpty(null), 'null is empty');
370
+ ok(_.isEmpty(), 'undefined is empty');
371
+ ok(_.isEmpty(''), 'the empty string is empty');
372
+ ok(!_.isEmpty('moe'), 'but other strings are not');
373
+
374
+ var obj = {one : 1};
375
+ delete obj.one;
376
+ ok(_.isEmpty(obj), 'deleting all the keys from an object empties it');
377
+ });
378
+
379
+ // Setup remote variables for iFrame tests.
380
+ var iframe = document.createElement('iframe');
381
+ jQuery(iframe).appendTo(document.body);
382
+ var iDoc = iframe.contentDocument || iframe.contentWindow.document;
383
+ iDoc.write(
384
+ "<script>\
385
+ parent.iElement = document.createElement('div');\
386
+ parent.iArguments = (function(){ return arguments; })(1, 2, 3);\
387
+ parent.iArray = [1, 2, 3];\
388
+ parent.iString = new String('hello');\
389
+ parent.iNumber = new Number(100);\
390
+ parent.iFunction = (function(){});\
391
+ parent.iDate = new Date();\
392
+ parent.iRegExp = /hi/;\
393
+ parent.iNaN = NaN;\
394
+ parent.iNull = null;\
395
+ parent.iBoolean = new Boolean(false);\
396
+ parent.iUndefined = undefined;\
397
+ parent.iObject = {};\
398
+ </script>"
399
+ );
400
+ iDoc.close();
401
+
402
+ test("isElement", function() {
403
+ ok(!_.isElement('div'), 'strings are not dom elements');
404
+ ok(_.isElement($('html')[0]), 'the html tag is a DOM element');
405
+ ok(_.isElement(iElement), 'even from another frame');
406
+ });
407
+
408
+ test("isArguments", function() {
409
+ var args = (function(){ return arguments; })(1, 2, 3);
410
+ ok(!_.isArguments('string'), 'a string is not an arguments object');
411
+ ok(!_.isArguments(_.isArguments), 'a function is not an arguments object');
412
+ ok(_.isArguments(args), 'but the arguments object is an arguments object');
413
+ ok(!_.isArguments(_.toArray(args)), 'but not when it\'s converted into an array');
414
+ ok(!_.isArguments([1,2,3]), 'and not vanilla arrays.');
415
+ ok(_.isArguments(iArguments), 'even from another frame');
416
+ });
417
+
418
+ test("isObject", function() {
419
+ ok(_.isObject(arguments), 'the arguments object is object');
420
+ ok(_.isObject([1, 2, 3]), 'and arrays');
421
+ ok(_.isObject($('html')[0]), 'and DOM element');
422
+ ok(_.isObject(iElement), 'even from another frame');
423
+ ok(_.isObject(function () {}), 'and functions');
424
+ ok(_.isObject(iFunction), 'even from another frame');
425
+ ok(!_.isObject(null), 'but not null');
426
+ ok(!_.isObject(undefined), 'and not undefined');
427
+ ok(!_.isObject('string'), 'and not string');
428
+ ok(!_.isObject(12), 'and not number');
429
+ ok(!_.isObject(true), 'and not boolean');
430
+ ok(_.isObject(new String('string')), 'but new String()');
431
+ });
432
+
433
+ test("isArray", function() {
434
+ ok(!_.isArray(arguments), 'the arguments object is not an array');
435
+ ok(_.isArray([1, 2, 3]), 'but arrays are');
436
+ ok(_.isArray(iArray), 'even from another frame');
437
+ });
438
+
439
+ test("isString", function() {
440
+ ok(!_.isString(document.body), 'the document body is not a string');
441
+ ok(_.isString([1, 2, 3].join(', ')), 'but strings are');
442
+ ok(_.isString(iString), 'even from another frame');
443
+ });
444
+
445
+ test("isNumber", function() {
446
+ ok(!_.isNumber('string'), 'a string is not a number');
447
+ ok(!_.isNumber(arguments), 'the arguments object is not a number');
448
+ ok(!_.isNumber(undefined), 'undefined is not a number');
449
+ ok(_.isNumber(3 * 4 - 7 / 10), 'but numbers are');
450
+ ok(_.isNumber(NaN), 'NaN *is* a number');
451
+ ok(_.isNumber(Infinity), 'Infinity is a number');
452
+ ok(_.isNumber(iNumber), 'even from another frame');
453
+ ok(!_.isNumber('1'), 'numeric strings are not numbers');
454
+ });
455
+
456
+ test("isBoolean", function() {
457
+ ok(!_.isBoolean(2), 'a number is not a boolean');
458
+ ok(!_.isBoolean("string"), 'a string is not a boolean');
459
+ ok(!_.isBoolean("false"), 'the string "false" is not a boolean');
460
+ ok(!_.isBoolean("true"), 'the string "true" is not a boolean');
461
+ ok(!_.isBoolean(arguments), 'the arguments object is not a boolean');
462
+ ok(!_.isBoolean(undefined), 'undefined is not a boolean');
463
+ ok(!_.isBoolean(NaN), 'NaN is not a boolean');
464
+ ok(!_.isBoolean(null), 'null is not a boolean');
465
+ ok(_.isBoolean(true), 'but true is');
466
+ ok(_.isBoolean(false), 'and so is false');
467
+ ok(_.isBoolean(iBoolean), 'even from another frame');
468
+ });
469
+
470
+ test("isFunction", function() {
471
+ ok(!_.isFunction([1, 2, 3]), 'arrays are not functions');
472
+ ok(!_.isFunction('moe'), 'strings are not functions');
473
+ ok(_.isFunction(_.isFunction), 'but functions are');
474
+ ok(_.isFunction(iFunction), 'even from another frame');
475
+ });
476
+
477
+ test("isDate", function() {
478
+ ok(!_.isDate(100), 'numbers are not dates');
479
+ ok(!_.isDate({}), 'objects are not dates');
480
+ ok(_.isDate(new Date()), 'but dates are');
481
+ ok(_.isDate(iDate), 'even from another frame');
482
+ });
483
+
484
+ test("isRegExp", function() {
485
+ ok(!_.isRegExp(_.identity), 'functions are not RegExps');
486
+ ok(_.isRegExp(/identity/), 'but RegExps are');
487
+ ok(_.isRegExp(iRegExp), 'even from another frame');
488
+ });
489
+
490
+ test("isFinite", function() {
491
+ ok(!_.isFinite(undefined), 'undefined is not Finite');
492
+ ok(!_.isFinite(null), 'null is not Finite');
493
+ ok(!_.isFinite(NaN), 'NaN is not Finite');
494
+ ok(!_.isFinite(Infinity), 'Infinity is not Finite');
495
+ ok(!_.isFinite(-Infinity), '-Infinity is not Finite');
496
+ ok(_.isFinite('12'), 'Numeric strings are numbers');
497
+ ok(!_.isFinite('1a'), 'Non numeric strings are not numbers');
498
+ ok(!_.isFinite(''), 'Empty strings are not numbers');
499
+ var obj = new Number(5);
500
+ ok(_.isFinite(obj), 'Number instances can be finite');
501
+ ok(_.isFinite(0), '0 is Finite');
502
+ ok(_.isFinite(123), 'Ints are Finite');
503
+ ok(_.isFinite(-12.44), 'Floats are Finite');
504
+ });
505
+
506
+ test("isNaN", function() {
507
+ ok(!_.isNaN(undefined), 'undefined is not NaN');
508
+ ok(!_.isNaN(null), 'null is not NaN');
509
+ ok(!_.isNaN(0), '0 is not NaN');
510
+ ok(_.isNaN(NaN), 'but NaN is');
511
+ ok(_.isNaN(iNaN), 'even from another frame');
512
+ ok(_.isNaN(new Number(NaN)), 'wrapped NaN is still NaN');
513
+ });
514
+
515
+ test("isNull", function() {
516
+ ok(!_.isNull(undefined), 'undefined is not null');
517
+ ok(!_.isNull(NaN), 'NaN is not null');
518
+ ok(_.isNull(null), 'but null is');
519
+ ok(_.isNull(iNull), 'even from another frame');
520
+ });
521
+
522
+ test("isUndefined", function() {
523
+ ok(!_.isUndefined(1), 'numbers are defined');
524
+ ok(!_.isUndefined(null), 'null is defined');
525
+ ok(!_.isUndefined(false), 'false is defined');
526
+ ok(!_.isUndefined(NaN), 'NaN is defined');
527
+ ok(_.isUndefined(), 'nothing is undefined');
528
+ ok(_.isUndefined(undefined), 'undefined is undefined');
529
+ ok(_.isUndefined(iUndefined), 'even from another frame');
530
+ });
531
+
532
+ if (window.ActiveXObject) {
533
+ test("IE host objects", function() {
534
+ var xml = new ActiveXObject("Msxml2.DOMDocument.3.0");
535
+ ok(!_.isNumber(xml));
536
+ ok(!_.isBoolean(xml));
537
+ ok(!_.isNaN(xml));
538
+ ok(!_.isFunction(xml));
539
+ ok(!_.isNull(xml));
540
+ ok(!_.isUndefined(xml));
541
+ });
542
+ }
543
+
544
+ test("tap", function() {
545
+ var intercepted = null;
546
+ var interceptor = function(obj) { intercepted = obj; };
547
+ var returned = _.tap(1, interceptor);
548
+ equal(intercepted, 1, "passes tapped object to interceptor");
549
+ equal(returned, 1, "returns tapped object");
550
+
551
+ returned = _([1,2,3]).chain().
552
+ map(function(n){ return n * 2; }).
553
+ max().
554
+ tap(interceptor).
555
+ value();
556
+ ok(returned == 6 && intercepted == 6, 'can use tapped objects in a chain');
557
+ });
558
+
559
+ test("has", function () {
560
+ var obj = {foo: "bar", func: function () {} };
561
+ ok (_.has(obj, "foo"), "has() checks that the object has a property.");
562
+ ok (_.has(obj, "baz") == false, "has() returns false if the object doesn't have the property.");
563
+ ok (_.has(obj, "func"), "has() works for functions too.");
564
+ obj.hasOwnProperty = null;
565
+ ok (_.has(obj, "foo"), "has() works even when the hasOwnProperty method is deleted.");
566
+ var child = {};
567
+ child.prototype = obj;
568
+ ok (_.has(child, "foo") == false, "has() does not check the prototype chain for a property.")
569
+ });
570
+ });