luca 0.9.9 → 0.9.42

Sign up to get free protection for your applications and to get access to all the features.
Files changed (604) hide show
  1. data/CHANGELOG +9 -153
  2. data/Gemfile +1 -10
  3. data/Gemfile.lock +40 -113
  4. data/Guardfile +25 -3
  5. data/README.md +57 -54
  6. data/ROADMAP +32 -15
  7. data/Rakefile +75 -24
  8. data/app.rb +46 -12
  9. data/{app/assets → assets}/images/glyphicons-halflings-white.png +0 -0
  10. data/{app/assets → assets}/images/glyphicons-halflings.png +0 -0
  11. data/assets/javascripts/dependencies/backbone-min.js +37 -0
  12. data/assets/javascripts/dependencies/backbone-query.min.js +1 -0
  13. data/assets/javascripts/dependencies/bootstrap.min.js +7 -0
  14. data/{vendor/assets/javascripts → assets/javascripts/dependencies}/codemirror-coffeescript.js +0 -0
  15. data/{vendor/assets/javascripts → assets/javascripts/dependencies}/codemirror-css.js +0 -0
  16. data/{vendor/assets/javascripts → assets/javascripts/dependencies}/codemirror-html.js +0 -0
  17. data/{vendor/assets/javascripts → assets/javascripts/dependencies}/codemirror-javascript.js +0 -0
  18. data/{vendor/assets/javascripts → assets/javascripts/dependencies}/codemirror-less.js +0 -0
  19. data/{vendor/assets/javascripts → assets/javascripts/dependencies}/codemirror-vim.js +0 -0
  20. data/{vendor/assets/javascripts → assets/javascripts/dependencies}/codemirror.js +0 -0
  21. data/assets/javascripts/dependencies/coffee-script.js +12189 -0
  22. data/{spec → assets}/javascripts/dependencies/jasmine-html.js +0 -0
  23. data/{spec → assets}/javascripts/dependencies/jasmine.js +0 -0
  24. data/assets/javascripts/dependencies/jquery.js +4 -0
  25. data/{vendor/assets/javascripts → assets/javascripts/dependencies}/modal.js +0 -0
  26. data/{vendor/assets/javascripts → assets/javascripts/dependencies}/modernizr.min.js +0 -0
  27. data/{vendor/assets/javascripts → assets/javascripts/dependencies}/prettify.js +0 -0
  28. data/{spec → assets}/javascripts/dependencies/sinon.js +0 -0
  29. data/{vendor/assets/javascripts → assets/javascripts/dependencies}/spin-min.js +0 -0
  30. data/assets/javascripts/dependencies/underscore-min.js +31 -0
  31. data/assets/javascripts/dependencies/underscore-string.min.js +14 -0
  32. data/assets/javascripts/dependencies.coffee +5 -0
  33. data/assets/javascripts/luca/index.coffee +1 -0
  34. data/assets/javascripts/luca-templates.js +1 -0
  35. data/assets/javascripts/luca-ui-base.coffee +1 -0
  36. data/assets/javascripts/luca-ui-bootstrap.js +1 -0
  37. data/assets/javascripts/luca-ui-development-tools.coffee +9 -0
  38. data/assets/javascripts/luca-ui-full.js +3 -0
  39. data/assets/javascripts/luca-ui-spec.coffee +2 -0
  40. data/assets/javascripts/luca-ui.js +3 -0
  41. data/assets/javascripts/sandbox/application.coffee +57 -0
  42. data/assets/javascripts/sandbox/config.coffee +7 -0
  43. data/assets/javascripts/sandbox/router.coffee +24 -0
  44. data/assets/javascripts/sandbox/templates/builder/component_list.luca +1 -0
  45. data/assets/javascripts/sandbox/templates/builder.luca +2 -0
  46. data/assets/javascripts/sandbox/templates/main.luca +53 -0
  47. data/assets/javascripts/sandbox/templates/sandbox/docs_index.luca +1 -0
  48. data/assets/javascripts/sandbox/templates/sandbox/navigation.luca +8 -0
  49. data/assets/javascripts/sandbox/templates/sandbox/readme.luca +30 -0
  50. data/assets/javascripts/sandbox/templates/sandbox.luca +1 -0
  51. data/assets/javascripts/sandbox/views/builder/builder_canvas.coffee +3 -0
  52. data/assets/javascripts/sandbox/views/builder/builder_editor.coffee +6 -0
  53. data/assets/javascripts/sandbox/views/builder/component_list.coffee +38 -0
  54. data/assets/javascripts/sandbox/views/builder/project_browser.coffee +14 -0
  55. data/assets/javascripts/sandbox/views/builder.coffee +133 -0
  56. data/assets/javascripts/sandbox/views/docs_controller.coffee +7 -0
  57. data/assets/javascripts/sandbox/views/inspector/instance_filter.coffee +18 -0
  58. data/{app/assets/stylesheets/luca/containers/modal_view.scss → assets/javascripts/sandbox/views/inspector/instance_list.coffee} +0 -0
  59. data/assets/javascripts/sandbox/views/inspector.coffee +11 -0
  60. data/assets/javascripts/sandbox/views/top_navigation.coffee +4 -0
  61. data/assets/javascripts/sandbox.coffee +7 -0
  62. data/assets/javascripts/spec-dependencies.coffee +4 -0
  63. data/assets/stylesheets/bootstrap-responsive.min.css +2 -0
  64. data/assets/stylesheets/bootstrap.min.css +727 -0
  65. data/{vendor/assets → assets}/stylesheets/codemirror-blackboard.css +0 -0
  66. data/{vendor/assets → assets}/stylesheets/codemirror-monokai.css +0 -0
  67. data/{vendor/assets → assets}/stylesheets/codemirror.css +0 -0
  68. data/{vendor/assets → assets}/stylesheets/jasmine.css +0 -0
  69. data/assets/stylesheets/luca-ui-bootstrap.css +4 -0
  70. data/assets/stylesheets/luca-ui-development-tools.css +5 -0
  71. data/assets/stylesheets/luca-ui-full.css +3 -0
  72. data/assets/stylesheets/luca-ui-spec.css +3 -0
  73. data/assets/stylesheets/luca-ui.css +3 -0
  74. data/assets/stylesheets/prettify.css +40 -0
  75. data/assets/stylesheets/sandbox/builder.scss +79 -0
  76. data/assets/stylesheets/sandbox/sandbox.scss +18 -0
  77. data/assets/stylesheets/sandbox.css +3 -0
  78. data/assets/stylesheets/themes/amelia-bootstrap.css +826 -0
  79. data/assets/stylesheets/themes/slate-bootstrap.css +797 -0
  80. data/assets/stylesheets/themes/superhero-bootstrap.css +830 -0
  81. data/config.ru +2 -1
  82. data/docs/{old/application.md → application.md} +0 -0
  83. data/docs/{old/collection.md → collection.md} +0 -0
  84. data/docs/{old/collection_manager.md → collection_manager.md} +0 -0
  85. data/docs/{old/container_philosophy.md → container_philosophy.md} +0 -0
  86. data/docs/{old/event_binding_helpers.md → event_binding_helpers.md} +0 -0
  87. data/docs/{old/method_caching_and_computed_properties.md → method_caching_and_computed_properties.md} +0 -0
  88. data/docs/{old/view.md → view.md} +0 -0
  89. data/lib/luca/code_browser.rb +55 -0
  90. data/lib/luca/command_line.rb +69 -0
  91. data/lib/luca/rails/engine.rb +0 -12
  92. data/lib/luca/rails/version.rb +2 -1
  93. data/lib/luca/rails.rb +3 -5
  94. data/lib/luca/template.rb +0 -2
  95. data/lib/luca.rb +1 -25
  96. data/luca.gemspec +7 -16
  97. data/site/assets/bootstrap.min.js +7 -0
  98. data/site/assets/dependencies.js +94 -0
  99. data/site/assets/glyphicons-halflings-white.png +0 -0
  100. data/site/assets/glyphicons-halflings.png +0 -0
  101. data/site/assets/luca-ui-bootstrap.css +1331 -0
  102. data/site/assets/luca-ui-bootstrap.js +9 -0
  103. data/site/assets/luca-ui-development-tools.css +234 -0
  104. data/site/assets/luca-ui-development-tools.js +18561 -0
  105. data/site/assets/luca-ui-development-tools.min.js +15 -0
  106. data/site/assets/luca-ui-full.min.js +8 -0
  107. data/site/assets/luca-ui.min.js +4 -0
  108. data/site/assets/sandbox.css +62 -0
  109. data/site/assets/sandbox.js +469 -0
  110. data/site/docs/application.html +41 -0
  111. data/site/docs/caching.html +43 -0
  112. data/site/docs/collection.html +75 -0
  113. data/site/docs/collection_manager.html +71 -0
  114. data/site/docs/containers.html +118 -0
  115. data/site/docs/events.html +153 -0
  116. data/site/docs/view.html +128 -0
  117. data/site/img/glyphicons-halflings-white.png +0 -0
  118. data/site/img/glyphicons-halflings.png +0 -0
  119. data/site/index.html +20 -0
  120. data/site/source-map.js +1 -0
  121. data/spec/{javascripts/components → components}/application_spec.coffee +0 -0
  122. data/spec/{javascripts/components → components}/collection_loader_view_spec.coffee +0 -0
  123. data/{site/source/app/assets/javascripts/docs/lib/util.coffee → spec/components/controller_spec.coffee} +0 -0
  124. data/spec/{javascripts/components → components}/fields/checkbox_array_spec.coffee +0 -0
  125. data/spec/components/form_view_spec.coffee +80 -0
  126. data/spec/{javascripts/components → components}/grid_view_spec.coffee +0 -0
  127. data/spec/{javascripts/components → components}/record_manager_spec.coffee +0 -0
  128. data/spec/{javascripts/components → components}/template_spec.coffee +0 -0
  129. data/spec/containers/card_view_spec.coffee +50 -0
  130. data/{site/source/app/assets/javascripts/docs/views/components/code_editor/index.coffee → spec/containers/column_view_spec.coffee} +0 -0
  131. data/spec/{javascripts/containers → containers}/modal_view_spec.coffee +0 -0
  132. data/spec/{javascripts/containers → containers}/panel_view_spec.coffee +0 -0
  133. data/spec/{javascripts/components/pagination_control_spec.coffee → containers/split_view_spec.coffee} +0 -0
  134. data/spec/{javascripts/containers → containers}/tab_view_spec.coffee +0 -0
  135. data/spec/{javascripts/containers → containers}/viewport_spec.coffee +0 -0
  136. data/spec/{javascripts/core → core}/collection_spec.coffee +1 -26
  137. data/spec/core/container_spec.coffee +66 -0
  138. data/spec/{javascripts/concerns/paginatable_spec.coffee → core/field_spec.coffee} +0 -0
  139. data/spec/{javascripts/core → core}/model_spec.coffee +3 -26
  140. data/spec/{javascripts/core → core}/observer_spec.coffee +0 -0
  141. data/spec/{javascripts/core → core}/view_spec.coffee +38 -114
  142. data/spec/{javascripts/core/framework_spec.coffee → framework_spec.coffee} +2 -31
  143. data/spec/{javascripts/helper.coffee → helper.coffee} +0 -0
  144. data/spec/{javascripts/managers → managers}/collection_manager_spec.coffee +0 -0
  145. data/spec/{javascripts/managers → managers}/socket_manager_spec.coffee +0 -0
  146. data/src/components/application.coffee +318 -0
  147. data/src/components/base_toolbar.coffee +15 -0
  148. data/{app/assets/javascripts/luca → src}/components/collection_loader_view.coffee +1 -3
  149. data/src/components/collection_view.coffee +131 -0
  150. data/src/components/controller.coffee +63 -0
  151. data/src/components/fields/button_field.coffee +38 -0
  152. data/{app/assets/javascripts/luca → src}/components/fields/checkbox_array.coffee +7 -18
  153. data/{app/assets/javascripts/luca → src}/components/fields/checkbox_field.coffee +10 -19
  154. data/{app/assets/javascripts/luca → src}/components/fields/file_upload_field.coffee +4 -5
  155. data/src/components/fields/hidden_field.coffee +12 -0
  156. data/src/components/fields/label_field.coffee +14 -0
  157. data/src/components/fields/select_field.coffee +97 -0
  158. data/src/components/fields/text_area_field.coffee +40 -0
  159. data/{app/assets/javascripts/luca → src}/components/fields/text_field.coffee +5 -16
  160. data/src/components/fields/type_ahead_field.coffee +22 -0
  161. data/src/components/form_button_toolbar.coffee +25 -0
  162. data/src/components/form_view.coffee +275 -0
  163. data/src/components/grid_view.coffee +269 -0
  164. data/src/components/index.coffee +1 -0
  165. data/src/components/load_mask.coffee +3 -0
  166. data/src/components/nav_bar.coffee +22 -0
  167. data/src/components/page_controller.coffee +2 -0
  168. data/{app/assets/javascripts/luca → src}/components/record_manager.coffee +0 -0
  169. data/{app/assets/javascripts/luca → src}/components/router.coffee +1 -6
  170. data/src/components/table_view.coffee +53 -0
  171. data/src/components/template.coffee +5 -0
  172. data/src/components/toolbar_dialog.coffee +25 -0
  173. data/src/containers/card_view.coffee +93 -0
  174. data/src/containers/column_view.coffee +42 -0
  175. data/{app/assets/javascripts/luca → src}/containers/modal_view.coffee +9 -9
  176. data/src/containers/page_view.coffee +2 -0
  177. data/{app/assets/javascripts/luca → src}/containers/panel_toolbar.coffee +84 -89
  178. data/src/containers/panel_view.coffee +23 -0
  179. data/src/containers/split_view.coffee +8 -0
  180. data/{app/assets/javascripts/luca → src}/containers/tab_view.coffee +21 -27
  181. data/{app/assets/javascripts/luca → src}/containers/viewport.coffee +18 -14
  182. data/{app/assets/javascripts/luca → src}/core/collection.coffee +51 -97
  183. data/src/core/container.coffee +374 -0
  184. data/{tutorials/component-definitions.md → src/core/core.coffee} +0 -0
  185. data/src/core/field.coffee +79 -0
  186. data/src/core/model.coffee +43 -0
  187. data/{app/assets/javascripts/luca → src}/core/observer.coffee +0 -0
  188. data/src/core/panel.coffee +118 -0
  189. data/{app/assets/javascripts/luca/core/registry → src/core}/registry.coffee +43 -63
  190. data/{app/assets/javascripts/luca/util → src/core}/script_loader.coffee +0 -0
  191. data/src/core/view.coffee +264 -0
  192. data/src/define.coffee +110 -0
  193. data/{app/assets/javascripts/luca → src}/framework.coffee +103 -98
  194. data/src/index.coffee +23 -0
  195. data/{app/assets/javascripts/luca → src}/managers/collection_manager.coffee +13 -37
  196. data/src/managers/socket_manager.coffee +54 -0
  197. data/{app/assets/javascripts/luca/concerns → src/modules}/deferrable.coffee +4 -5
  198. data/src/modules/grid_layout.coffee +3 -0
  199. data/{app/assets/javascripts/luca/concerns/loadmaskable.coffee → src/modules/load_mask.coffee} +11 -23
  200. data/{app/assets/javascripts/luca/concerns → src/modules}/local_storage.coffee +0 -0
  201. data/src/plugins/development_tool_helpers.coffee +21 -0
  202. data/src/plugins/events.coffee +54 -0
  203. data/src/samples/definition.coffee +49 -0
  204. data/{tutorials/component-definitions/01_intro.md → src/stylesheets/base.scss} +0 -0
  205. data/{app/assets/stylesheets/luca → src/stylesheets}/components/checkbox_array.scss +1 -1
  206. data/src/stylesheets/components/form_view.scss +59 -0
  207. data/{app/assets/stylesheets/luca → src/stylesheets}/components/grid_view.scss +0 -0
  208. data/{app/assets/stylesheets/luca → src/stylesheets}/components/load_mask.scss +0 -0
  209. data/src/stylesheets/components/toolbar.scss +0 -0
  210. data/{app/assets/stylesheets/luca → src/stylesheets}/components/viewport.scss +4 -1
  211. data/src/stylesheets/containers/container.scss +16 -0
  212. data/src/stylesheets/containers/modal_view.scss +0 -0
  213. data/{app/assets/stylesheets/luca → src/stylesheets}/containers/panels.scss +0 -0
  214. data/{app/assets/stylesheets/luca → src/stylesheets}/containers/tab_view.scss +5 -5
  215. data/{app/assets/stylesheets/luca → src/stylesheets}/normalize.scss +0 -0
  216. data/src/stylesheets/tools/class_browser.scss +32 -0
  217. data/src/stylesheets/tools/code_editor.scss +24 -0
  218. data/src/stylesheets/tools/component_tester.scss +26 -0
  219. data/{app/assets/stylesheets/luca/development → src/stylesheets/tools}/console.scss +0 -0
  220. data/src/templates/components/bootstrap_form_controls.luca +7 -0
  221. data/src/templates/components/collection_loader_view.luca +5 -0
  222. data/src/templates/components/form_alert +0 -0
  223. data/src/templates/components/form_alert.luca +3 -0
  224. data/src/templates/components/grid_view.luca +7 -0
  225. data/src/templates/components/grid_view_empty_text.luca +3 -0
  226. data/src/templates/components/load_mask.luca +3 -0
  227. data/src/templates/components/nav_bar.luca +2 -0
  228. data/src/templates/containers/basic.luca +1 -0
  229. data/src/templates/containers/tab_selector_container.luca +8 -0
  230. data/src/templates/containers/tab_view.luca +2 -0
  231. data/src/templates/containers/toolbar_wrapper.luca +1 -0
  232. data/src/templates/fields/button_field.luca +2 -0
  233. data/src/templates/fields/button_field_link.luca +5 -0
  234. data/src/templates/fields/checkbox_array.luca +4 -0
  235. data/src/templates/fields/checkbox_array_item.luca +4 -0
  236. data/src/templates/fields/checkbox_field.luca +9 -0
  237. data/src/templates/fields/file_upload_field.luca +8 -0
  238. data/src/templates/fields/hidden_field.luca +1 -0
  239. data/src/templates/fields/select_field.luca +8 -0
  240. data/src/templates/fields/text_area_field.luca +8 -0
  241. data/src/templates/fields/text_field.luca +17 -0
  242. data/src/templates/sample/contents.luca +1 -0
  243. data/src/templates/sample/welcome.luca +1 -0
  244. data/src/templates/table_view.luca +4 -0
  245. data/src/tools/application_inspector.coffee +2 -0
  246. data/src/tools/code_editor.coffee +258 -0
  247. data/{app/assets/javascripts/luca/development → src/tools}/code_mirror_field.coffee +1 -2
  248. data/src/tools/coffee_script_editor.coffee +82 -0
  249. data/src/tools/collection_inspector.coffee +4 -0
  250. data/src/tools/collections/components.coffee +59 -0
  251. data/src/tools/collections/instances.coffee +15 -0
  252. data/src/tools/component_tester.coffee +462 -0
  253. data/{app/assets/javascripts/luca/development → src/tools}/console.coffee +24 -55
  254. data/src/tools/models/components.coffee +25 -0
  255. data/src/tools/models/instance.coffee +2 -0
  256. data/src/tools/templates/component_tester/help.luca +14 -0
  257. data/{app/assets/javascripts/luca/util/luca.coffee → src/util.coffee} +6 -90
  258. data/vendor/assets/javascripts/luca-ui-development-tools.js +18533 -0
  259. data/vendor/assets/javascripts/luca-ui-development-tools.min.js +15 -0
  260. data/vendor/assets/javascripts/luca-ui-full.js +4806 -0
  261. data/vendor/assets/javascripts/luca-ui-full.min.js +8 -0
  262. data/vendor/assets/javascripts/luca-ui-templates.js +24 -0
  263. data/vendor/assets/javascripts/luca-ui.js +1703 -4394
  264. data/vendor/assets/javascripts/luca-ui.min.js +4 -5
  265. data/vendor/assets/luca-ui/base.css +85 -0
  266. data/vendor/assets/luca-ui/components/application.js +91 -0
  267. data/vendor/assets/luca-ui/components/base_toolbar.js +23 -0
  268. data/vendor/assets/luca-ui/components/controller.js +38 -0
  269. data/vendor/assets/luca-ui/components/fields/button_field.js +45 -0
  270. data/vendor/assets/luca-ui/components/fields/checkbox_field.js +43 -0
  271. data/vendor/assets/luca-ui/components/fields/file_upload_field.js +20 -0
  272. data/vendor/assets/luca-ui/components/fields/hidden_field.js +20 -0
  273. data/vendor/assets/luca-ui/components/fields/select_field.js +97 -0
  274. data/vendor/assets/luca-ui/components/fields/text_area_field.js +48 -0
  275. data/vendor/assets/luca-ui/components/fields/text_field.js +46 -0
  276. data/vendor/assets/luca-ui/components/fields/type_ahead_field.js +13 -0
  277. data/vendor/assets/luca-ui/components/form_button_toolbar.js +32 -0
  278. data/vendor/assets/luca-ui/components/form_view.css +32 -0
  279. data/vendor/assets/luca-ui/components/form_view.js +207 -0
  280. data/{app/assets/stylesheets/luca/components/table_view.scss → vendor/assets/luca-ui/components/grid_view.css} +51 -60
  281. data/vendor/assets/luca-ui/components/grid_view.js +202 -0
  282. data/vendor/assets/luca-ui/components/record_manager.js +207 -0
  283. data/vendor/assets/luca-ui/components/router.js +36 -0
  284. data/vendor/assets/luca-ui/components/template.js +26 -0
  285. data/vendor/assets/luca-ui/components/toolbar.css +11 -0
  286. data/vendor/assets/luca-ui/containers/card_view.js +98 -0
  287. data/vendor/assets/luca-ui/containers/column_view.js +52 -0
  288. data/vendor/assets/luca-ui/containers/container.css +3 -0
  289. data/vendor/assets/luca-ui/containers/modal_view.css +0 -0
  290. data/vendor/assets/luca-ui/containers/modal_view.js +87 -0
  291. data/vendor/assets/luca-ui/containers/panel_view.js +34 -0
  292. data/vendor/assets/luca-ui/containers/split_view.js +13 -0
  293. data/vendor/assets/luca-ui/containers/tab_view.css +16 -0
  294. data/vendor/assets/luca-ui/containers/tab_view.js +80 -0
  295. data/vendor/assets/luca-ui/containers/viewport.js +18 -0
  296. data/vendor/assets/luca-ui/core/collection.js +221 -0
  297. data/vendor/assets/luca-ui/core/container.js +205 -0
  298. data/vendor/assets/luca-ui/core/field.js +59 -0
  299. data/vendor/assets/luca-ui/core/observer.js +42 -0
  300. data/vendor/assets/luca-ui/core/view.js +127 -0
  301. data/vendor/assets/luca-ui/framework.js +110 -0
  302. data/vendor/assets/luca-ui/index.js +5 -0
  303. data/vendor/assets/luca-ui/managers/collection_manager.js +98 -0
  304. data/vendor/assets/luca-ui/managers/socket_manager.js +52 -0
  305. data/vendor/assets/luca-ui/modules/deferrable.js +21 -0
  306. data/vendor/assets/luca-ui/modules/local_storage.js +81 -0
  307. data/vendor/assets/luca-ui/normalize.css +359 -0
  308. data/vendor/assets/luca-ui/stylesheets/base.css +85 -0
  309. data/vendor/assets/luca-ui/stylesheets/components/form_view.css +32 -0
  310. data/vendor/assets/luca-ui/stylesheets/components/grid_view.css +76 -0
  311. data/vendor/assets/luca-ui/stylesheets/components/toolbar.css +11 -0
  312. data/vendor/assets/luca-ui/stylesheets/containers/container.css +3 -0
  313. data/vendor/assets/luca-ui/stylesheets/containers/modal_view.css +0 -0
  314. data/vendor/assets/luca-ui/stylesheets/containers/tab_view.css +16 -0
  315. data/vendor/assets/luca-ui/stylesheets/normalize.css +359 -0
  316. data/vendor/assets/luca-ui/templates/components/bootstrap_form_controls.js +4 -0
  317. data/vendor/assets/luca-ui/templates/components/form_view.js +4 -0
  318. data/vendor/assets/luca-ui/templates/components/grid_view.js +4 -0
  319. data/vendor/assets/luca-ui/templates/components/grid_view_empty_text.js +4 -0
  320. data/vendor/assets/luca-ui/templates/containers/basic.js +4 -0
  321. data/vendor/assets/luca-ui/templates/containers/tab_selector_container.js +4 -0
  322. data/vendor/assets/luca-ui/templates/containers/tab_view.js +4 -0
  323. data/vendor/assets/luca-ui/templates/containers/toolbar_wrapper.js +4 -0
  324. data/vendor/assets/luca-ui/templates/fields/button_field.js +4 -0
  325. data/vendor/assets/luca-ui/templates/fields/button_field_link.js +4 -0
  326. data/vendor/assets/luca-ui/templates/fields/checkbox_field.js +4 -0
  327. data/vendor/assets/luca-ui/templates/fields/file_upload_field.js +4 -0
  328. data/vendor/assets/luca-ui/templates/fields/hidden_field.js +4 -0
  329. data/vendor/assets/luca-ui/templates/fields/select_field.js +4 -0
  330. data/vendor/assets/luca-ui/templates/fields/text_area_field.js +4 -0
  331. data/vendor/assets/luca-ui/templates/fields/text_field.js +4 -0
  332. data/vendor/assets/luca-ui/templates/sample/contents.js +4 -0
  333. data/vendor/assets/luca-ui/templates/sample/welcome.js +4 -0
  334. data/vendor/assets/stylesheets/luca-ui.css +471 -68
  335. data/views/jasmine.erb +2 -2
  336. metadata +328 -496
  337. data/app/assets/javascripts/luca/basic.coffee +0 -8
  338. data/app/assets/javascripts/luca/components/application.coffee +0 -530
  339. data/app/assets/javascripts/luca/components/collection_view.coffee +0 -211
  340. data/app/assets/javascripts/luca/components/controller.coffee +0 -176
  341. data/app/assets/javascripts/luca/components/fields/base.coffee +0 -144
  342. data/app/assets/javascripts/luca/components/fields/button_field.coffee +0 -91
  343. data/app/assets/javascripts/luca/components/fields/hidden_field.coffee +0 -11
  344. data/app/assets/javascripts/luca/components/fields/label_field.coffee +0 -12
  345. data/app/assets/javascripts/luca/components/fields/select_field.coffee +0 -159
  346. data/app/assets/javascripts/luca/components/fields/text_area_field.coffee +0 -57
  347. data/app/assets/javascripts/luca/components/fields/type_ahead_field.coffee +0 -20
  348. data/app/assets/javascripts/luca/components/form_view.coffee +0 -421
  349. data/app/assets/javascripts/luca/components/grid_layout_view.coffee +0 -42
  350. data/app/assets/javascripts/luca/components/index.coffee +0 -7
  351. data/app/assets/javascripts/luca/components/load_mask.coffee +0 -8
  352. data/app/assets/javascripts/luca/components/multi_collection_view.coffee +0 -92
  353. data/app/assets/javascripts/luca/components/nav_bar.coffee +0 -80
  354. data/app/assets/javascripts/luca/components/page.coffee +0 -70
  355. data/app/assets/javascripts/luca/components/pagination_control.coffee +0 -104
  356. data/app/assets/javascripts/luca/components/simple_collection_view.coffee +0 -10
  357. data/app/assets/javascripts/luca/components/table_view.coffee +0 -93
  358. data/app/assets/javascripts/luca/components/table_view_scrollable.coffee +0 -23
  359. data/app/assets/javascripts/luca/concerns/application_event_bindings.coffee +0 -19
  360. data/app/assets/javascripts/luca/concerns/collection_event_bindings.coffee +0 -47
  361. data/app/assets/javascripts/luca/concerns/development_tool_helpers.coffee +0 -30
  362. data/app/assets/javascripts/luca/concerns/dom_helpers.coffee +0 -61
  363. data/app/assets/javascripts/luca/concerns/enhanced_properties.coffee +0 -23
  364. data/app/assets/javascripts/luca/concerns/filterable.coffee +0 -101
  365. data/app/assets/javascripts/luca/concerns/form_model_bindings.coffee +0 -20
  366. data/app/assets/javascripts/luca/concerns/grid_layout.coffee +0 -15
  367. data/app/assets/javascripts/luca/concerns/modal_view.coffee +0 -63
  368. data/app/assets/javascripts/luca/concerns/model_presenter.coffee +0 -23
  369. data/app/assets/javascripts/luca/concerns/paginatable.coffee +0 -79
  370. data/app/assets/javascripts/luca/concerns/query_collection_bindings.coffee +0 -52
  371. data/app/assets/javascripts/luca/concerns/sortable.coffee +0 -69
  372. data/app/assets/javascripts/luca/concerns/state_model.coffee +0 -58
  373. data/app/assets/javascripts/luca/concerns/templating.coffee +0 -13
  374. data/app/assets/javascripts/luca/config.coffee +0 -54
  375. data/app/assets/javascripts/luca/containers/card_view.coffee +0 -178
  376. data/app/assets/javascripts/luca/containers/container.coffee +0 -711
  377. data/app/assets/javascripts/luca/containers/index.coffee +0 -2
  378. data/app/assets/javascripts/luca/containers/page_controller.coffee +0 -25
  379. data/app/assets/javascripts/luca/core/events.coffee +0 -114
  380. data/app/assets/javascripts/luca/core/index.coffee +0 -12
  381. data/app/assets/javascripts/luca/core/model.coffee +0 -56
  382. data/app/assets/javascripts/luca/core/panel.coffee +0 -124
  383. data/app/assets/javascripts/luca/core/registry/component_definition.coffee +0 -319
  384. data/app/assets/javascripts/luca/core/registry/concerns.coffee +0 -70
  385. data/app/assets/javascripts/luca/core/registry/index.coffee +0 -4
  386. data/app/assets/javascripts/luca/core/registry/meta_data.coffee +0 -99
  387. data/app/assets/javascripts/luca/core/templates.coffee +0 -51
  388. data/app/assets/javascripts/luca/core/view.coffee +0 -383
  389. data/app/assets/javascripts/luca/dependencies.coffee +0 -9
  390. data/app/assets/javascripts/luca/development/code_sync_manager.coffee +0 -173
  391. data/app/assets/javascripts/luca/development/component.coffee +0 -76
  392. data/app/assets/javascripts/luca/development/components.coffee +0 -57
  393. data/app/assets/javascripts/luca/development/index.coffee +0 -5
  394. data/app/assets/javascripts/luca/index.coffee +0 -9
  395. data/app/assets/javascripts/luca/managers/index.coffee +0 -2
  396. data/app/assets/javascripts/luca/managers/socket_manager.coffee +0 -89
  397. data/app/assets/javascripts/luca/templates/components/bootstrap_form_controls.jst.ejs +0 -10
  398. data/app/assets/javascripts/luca/templates/components/collection_loader_view.jst.ejs +0 -6
  399. data/app/assets/javascripts/luca/templates/components/form_alert.jst.ejs +0 -4
  400. data/app/assets/javascripts/luca/templates/components/grid_view.jst.ejs +0 -11
  401. data/app/assets/javascripts/luca/templates/components/grid_view_empty_text.jst.ejs +0 -3
  402. data/app/assets/javascripts/luca/templates/components/load_mask.jst.ejs +0 -5
  403. data/app/assets/javascripts/luca/templates/components/nav_bar.jst.ejs +0 -19
  404. data/app/assets/javascripts/luca/templates/components/pagination.jst.ejs +0 -10
  405. data/app/assets/javascripts/luca/templates/components/table_view.jst.ejs +0 -4
  406. data/app/assets/javascripts/luca/templates/containers/basic.jst.ejs +0 -1
  407. data/app/assets/javascripts/luca/templates/containers/tab_selector_container.jst.ejs +0 -12
  408. data/app/assets/javascripts/luca/templates/containers/tab_view.jst.ejs +0 -2
  409. data/app/assets/javascripts/luca/templates/containers/toolbar_wrapper.jst.ejs +0 -1
  410. data/app/assets/javascripts/luca/templates/fields/button_field.jst.ejs +0 -2
  411. data/app/assets/javascripts/luca/templates/fields/button_field_link.jst.ejs +0 -6
  412. data/app/assets/javascripts/luca/templates/fields/checkbox_array.jst.ejs +0 -4
  413. data/app/assets/javascripts/luca/templates/fields/checkbox_array_item.jst.ejs +0 -3
  414. data/app/assets/javascripts/luca/templates/fields/checkbox_field.jst.ejs +0 -10
  415. data/app/assets/javascripts/luca/templates/fields/file_upload_field.jst.ejs +0 -10
  416. data/app/assets/javascripts/luca/templates/fields/hidden_field.jst.ejs +0 -1
  417. data/app/assets/javascripts/luca/templates/fields/select_field.jst.ejs +0 -11
  418. data/app/assets/javascripts/luca/templates/fields/text_area_field.jst.ejs +0 -11
  419. data/app/assets/javascripts/luca/templates/fields/text_field.jst.ejs +0 -16
  420. data/app/assets/javascripts/luca/util/deprecations.coffee +0 -18
  421. data/app/assets/javascripts/luca/util/index.coffee +0 -4
  422. data/app/assets/javascripts/luca/util/keybindings.coffee +0 -24
  423. data/app/assets/javascripts/luca/util/logging.coffee +0 -30
  424. data/app/assets/javascripts/luca-ui.js +0 -1
  425. data/app/assets/stylesheets/luca/components/form_view.scss +0 -7
  426. data/app/assets/stylesheets/luca/containers/container.scss +0 -19
  427. data/app/assets/stylesheets/luca/development/index.css +0 -3
  428. data/app/assets/stylesheets/luca/index.css +0 -4
  429. data/bin/luca +0 -14
  430. data/docs/framework.json +0 -1
  431. data/docs/luca-framework-documentation.js +0 -1
  432. data/lib/generators/luca/application/application_generator.rb +0 -75
  433. data/lib/generators/luca/application/templates/controller.rb +0 -4
  434. data/lib/generators/luca/application/templates/index.html.erb +0 -19
  435. data/lib/generators/luca/application/templates/index.html.haml +0 -7
  436. data/lib/generators/luca/application/templates/javascripts/application.coffee +0 -18
  437. data/lib/generators/luca/application/templates/javascripts/collection_manager.coffee +0 -2
  438. data/lib/generators/luca/application/templates/javascripts/config.coffee +0 -3
  439. data/lib/generators/luca/application/templates/javascripts/dependencies.coffee +0 -3
  440. data/lib/generators/luca/application/templates/javascripts/home.jst.ejs +0 -2
  441. data/lib/generators/luca/application/templates/javascripts/index.coffee +0 -15
  442. data/lib/generators/luca/application/templates/javascripts/router.coffee +0 -4
  443. data/lib/guard/luca.rb +0 -84
  444. data/lib/luca/asset_compiler.rb +0 -117
  445. data/lib/luca/cli/generate.rb +0 -37
  446. data/lib/luca/cli/server.rb +0 -20
  447. data/lib/luca/cli/sync.rb +0 -40
  448. data/lib/luca/cli/watch.rb +0 -16
  449. data/lib/luca/cli.rb +0 -68
  450. data/lib/luca/collection/endpoint.rb +0 -38
  451. data/lib/luca/collection/file_backend.rb +0 -121
  452. data/lib/luca/collection/redis_backend.rb +0 -153
  453. data/lib/luca/collection.rb +0 -64
  454. data/lib/luca/compiled_asset.rb +0 -61
  455. data/lib/luca/component_definition.rb +0 -356
  456. data/lib/luca/luca_application.rb +0 -258
  457. data/lib/luca/project.rb +0 -73
  458. data/lib/luca/project_harness.rb +0 -96
  459. data/lib/luca/server.rb +0 -7
  460. data/lib/luca/stylesheet.rb +0 -35
  461. data/lib/luca/template_asset.rb +0 -64
  462. data/lib/luca/version.rb +0 -3
  463. data/lib/luca/watcher.rb +0 -72
  464. data/lib/railties/luca/tasks.rake +0 -38
  465. data/site/.bundle/config +0 -2
  466. data/site/.gitignore +0 -5
  467. data/site/.rvmrc +0 -1
  468. data/site/CHANGELOG.md +0 -41
  469. data/site/DOCS.md +0 -41
  470. data/site/Gemfile +0 -8
  471. data/site/Gemfile.lock +0 -134
  472. data/site/LICENSE.md +0 -19
  473. data/site/config.rb +0 -84
  474. data/site/helpers/site_helpers.rb +0 -20
  475. data/site/html5bp-docs/README.md +0 -38
  476. data/site/html5bp-docs/contribute.md +0 -104
  477. data/site/html5bp-docs/crossdomain.md +0 -21
  478. data/site/html5bp-docs/css.md +0 -135
  479. data/site/html5bp-docs/extend.md +0 -507
  480. data/site/html5bp-docs/faq.md +0 -77
  481. data/site/html5bp-docs/htaccess.md +0 -323
  482. data/site/html5bp-docs/html.md +0 -170
  483. data/site/html5bp-docs/js.md +0 -31
  484. data/site/html5bp-docs/misc.md +0 -25
  485. data/site/html5bp-docs/usage.md +0 -109
  486. data/site/readme.md +0 -47
  487. data/site/source/.htaccess +0 -540
  488. data/site/source/404.html +0 -157
  489. data/site/source/app/assets/javascripts/dependencies.js.coffee +0 -6
  490. data/site/source/app/assets/javascripts/docs/application.coffee +0 -64
  491. data/site/source/app/assets/javascripts/docs/collections/docs_documentation.coffee +0 -17
  492. data/site/source/app/assets/javascripts/docs/collections/github_repositories.coffee +0 -7
  493. data/site/source/app/assets/javascripts/docs/collections/index.coffee +0 -1
  494. data/site/source/app/assets/javascripts/docs/collections/luca_documentation.coffee +0 -17
  495. data/site/source/app/assets/javascripts/docs/collections/public_gists.coffee +0 -4
  496. data/site/source/app/assets/javascripts/docs/config.coffee +0 -5
  497. data/site/source/app/assets/javascripts/docs/index.coffee +0 -12
  498. data/site/source/app/assets/javascripts/docs/lib/router.coffee +0 -3
  499. data/site/source/app/assets/javascripts/docs/models/component.coffee +0 -99
  500. data/site/source/app/assets/javascripts/docs/models/github_repository.coffee +0 -3
  501. data/site/source/app/assets/javascripts/docs/models/index.coffee +0 -1
  502. data/site/source/app/assets/javascripts/docs/templates/component_documentation.jst.ejs +0 -55
  503. data/site/source/app/assets/javascripts/docs/templates/examples_browser/overview.jst.ejs +0 -4
  504. data/site/source/app/assets/javascripts/docs/templates/examples_browser/selector.jst.ejs +0 -11
  505. data/site/source/app/assets/javascripts/docs/templates/github_repository.jst.ejs +0 -4
  506. data/site/source/app/assets/javascripts/docs/templates/layouts/main.jst.ejs +0 -4
  507. data/site/source/app/assets/javascripts/docs/templates/left_navigation.jst.ejs +0 -5
  508. data/site/source/app/assets/javascripts/docs/templates/pages/getting_started.jst.ejs +0 -78
  509. data/site/source/app/assets/javascripts/docs/templates/pages/home.jst.ejs +0 -57
  510. data/site/source/app/assets/javascripts/docs/views/components/code_editor.coffee +0 -45
  511. data/site/source/app/assets/javascripts/docs/views/components/component_documentation.coffee +0 -72
  512. data/site/source/app/assets/javascripts/docs/views/index.coffee +0 -3
  513. data/site/source/app/assets/javascripts/docs/views/pages/browse_source/details.coffee +0 -37
  514. data/site/source/app/assets/javascripts/docs/views/pages/browse_source/list.coffee +0 -31
  515. data/site/source/app/assets/javascripts/docs/views/pages/browse_source.coffee +0 -46
  516. data/site/source/app/assets/javascripts/docs/views/pages/component_editor.coffee +0 -10
  517. data/site/source/app/assets/javascripts/docs/views/pages/examples_browser/docs.coffee +0 -12
  518. data/site/source/app/assets/javascripts/docs/views/pages/examples_browser/source.coffee +0 -13
  519. data/site/source/app/assets/javascripts/docs/views/pages/examples_browser.coffee +0 -102
  520. data/site/source/app/assets/javascripts/docs/views/pages/home.coffee +0 -10
  521. data/site/source/app/assets/javascripts/docs/views/views/api_browser/index.coffee +0 -43
  522. data/site/source/app/assets/javascripts/docs/views/views/collection_view_examples/grid_layout_view_example.coffee +0 -14
  523. data/site/source/app/assets/javascripts/docs/views/views/collection_view_examples/table_view_example.coffee +0 -39
  524. data/site/source/app/assets/javascripts/docs/views/views/form_view_examples/basic_example.coffee +0 -38
  525. data/site/source/app/assets/javascripts/docs/views/views/form_view_examples/complex_layout.coffee +0 -110
  526. data/site/source/app/assets/javascripts/docs/views/views/top_navigation.coffee +0 -6
  527. data/site/source/app/assets/javascripts/docs-docs.js +0 -1
  528. data/site/source/app/assets/javascripts/luca-docs.js +0 -1
  529. data/site/source/app/assets/javascripts/luca-framework-documentation.js +0 -1
  530. data/site/source/app/assets/javascripts/site.js.coffee +0 -4
  531. data/site/source/app/assets/javascripts/vendor/codemirror.js +0 -4786
  532. data/site/source/app/assets/javascripts/vendor/coffeescript.js +0 -346
  533. data/site/source/app/assets/javascripts/vendor/css.js +0 -465
  534. data/site/source/app/assets/javascripts/vendor/htmlmixed.js +0 -84
  535. data/site/source/app/assets/javascripts/vendor/javascript.js +0 -422
  536. data/site/source/app/assets/javascripts/vendor/js-beautify.js +0 -1353
  537. data/site/source/app/assets/javascripts/vendor/modernizr-2.6.1.min.js +0 -4
  538. data/site/source/app/assets/javascripts/vendor/vim.js +0 -2511
  539. data/site/source/app/assets/stylesheets/docs/api-browser.css.scss +0 -5
  540. data/site/source/app/assets/stylesheets/docs/application.css.scss +0 -35
  541. data/site/source/app/assets/stylesheets/docs/browse-source.css.scss +0 -5
  542. data/site/source/app/assets/stylesheets/docs/scrollable-table.css.scss +0 -5
  543. data/site/source/app/assets/stylesheets/site.css.scss +0 -2
  544. data/site/source/app/assets/stylesheets/vendor/codemirror.css +0 -240
  545. data/site/source/app/assets/stylesheets/vendor/prettify-tomorrow-night-bright.css +0 -160
  546. data/site/source/app/assets/stylesheets/vendor/twilight.css +0 -26
  547. data/site/source/crossdomain.xml +0 -15
  548. data/site/source/documentation.html.haml +0 -1
  549. data/site/source/favicon_base.png +0 -0
  550. data/site/source/humans.txt +0 -15
  551. data/site/source/images/background.png +0 -0
  552. data/site/source/images/middleman.png +0 -0
  553. data/site/source/index.html.haml +0 -1
  554. data/site/source/layouts/layout.haml +0 -55
  555. data/site/source/readme.md +0 -63
  556. data/site/source/robots.txt +0 -3
  557. data/spec/javascripts/components/collection_view_spec.coffee +0 -59
  558. data/spec/javascripts/components/controller_spec.coffee +0 -62
  559. data/spec/javascripts/components/form_view_spec.coffee +0 -162
  560. data/spec/javascripts/components/multi_collection_view_spec.coffee +0 -5
  561. data/spec/javascripts/components/table_view_spec.coffee +0 -17
  562. data/spec/javascripts/concerns/collection_event_bindings_spec.coffee +0 -15
  563. data/spec/javascripts/concerns/dom_helpers_spec.coffee +0 -16
  564. data/spec/javascripts/concerns/filterable_spec.coffee +0 -25
  565. data/spec/javascripts/concerns/model_presenter_spec.coffee +0 -31
  566. data/spec/javascripts/concerns/state_model_spec.coffee +0 -55
  567. data/spec/javascripts/containers/card_view_spec.coffee +0 -108
  568. data/spec/javascripts/core/concerns_spec.coffee +0 -88
  569. data/spec/javascripts/core/container_spec.coffee +0 -287
  570. data/spec/javascripts/core/define_spec.coffee +0 -116
  571. data/spec/javascripts/core/events_spec.coffee +0 -26
  572. data/spec/javascripts/core/field_spec.coffee +0 -4
  573. data/spec/javascripts/core/util_spec.coffee +0 -24
  574. data/spec/javascripts/dependencies/index.coffee +0 -3
  575. data/spec/lib/component_definition_spec.rb +0 -63
  576. data/spec/lib/input_compiler_spec.rb +0 -9
  577. data/spec/lib/luca_application_spec.rb +0 -30
  578. data/spec/support/fixtures/application.coffee +0 -45
  579. data/spec/support/fixtures/component.coffee +0 -34
  580. data/tutorials/component-driven-design.md +0 -140
  581. data/tutorials/structure-of-a-project.md +0 -63
  582. data/vendor/assets/javascripts/backbone-ext.js +0 -21
  583. data/vendor/assets/javascripts/backbone-min.js +0 -42
  584. data/vendor/assets/javascripts/backbone-query.min.js +0 -1
  585. data/vendor/assets/javascripts/bootstrap.min.js +0 -7
  586. data/vendor/assets/javascripts/codemirror-ui.js +0 -503
  587. data/vendor/assets/javascripts/hogan.js +0 -707
  588. data/vendor/assets/javascripts/inflections.js +0 -656
  589. data/vendor/assets/javascripts/jasmine-html.js +0 -190
  590. data/vendor/assets/javascripts/jasmine.js +0 -2476
  591. data/vendor/assets/javascripts/jquery.js +0 -5
  592. data/vendor/assets/javascripts/keymaster.min.js +0 -4
  593. data/vendor/assets/javascripts/luca-dependencies.min.js +0 -8
  594. data/vendor/assets/javascripts/luca-development.min.js +0 -1
  595. data/vendor/assets/javascripts/luca-spec.js +0 -11
  596. data/vendor/assets/javascripts/luca.full.min.js +0 -12
  597. data/vendor/assets/javascripts/luca.min.js +0 -5
  598. data/vendor/assets/javascripts/sinon.js +0 -3469
  599. data/vendor/assets/javascripts/underscore-min.js +0 -1
  600. data/vendor/assets/javascripts/underscore-string.min.js +0 -1
  601. data/vendor/assets/stylesheets/bootstrap-responsive.min.css +0 -9
  602. data/vendor/assets/stylesheets/bootstrap.min.css +0 -9
  603. data/vendor/assets/stylesheets/luca-components.css +0 -202
  604. data/vendor/assets/stylesheets/luca-development.css +0 -23
@@ -1,3469 +0,0 @@
1
- /**
2
- * Sinon.JS 1.3.1, 2012/01/04
3
- *
4
- * @author Christian Johansen (christian@cjohansen.no)
5
- *
6
- * (The BSD License)
7
- *
8
- * Copyright (c) 2010-2011, Christian Johansen, christian@cjohansen.no
9
- * All rights reserved.
10
- *
11
- * Redistribution and use in source and binary forms, with or without modification,
12
- * are permitted provided that the following conditions are met:
13
- *
14
- * * Redistributions of source code must retain the above copyright notice,
15
- * this list of conditions and the following disclaimer.
16
- * * Redistributions in binary form must reproduce the above copyright notice,
17
- * this list of conditions and the following disclaimer in the documentation
18
- * and/or other materials provided with the distribution.
19
- * * Neither the name of Christian Johansen nor the names of his contributors
20
- * may be used to endorse or promote products derived from this software
21
- * without specific prior written permission.
22
- *
23
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
27
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
- */
34
-
35
- "use strict";
36
- var sinon = (function () {
37
- var buster = (function (buster, setTimeout) {
38
- function extend(target) {
39
- if (!target) {
40
- return;
41
- }
42
-
43
- for (var i = 1, l = arguments.length, prop; i < l; ++i) {
44
- for (prop in arguments[i]) {
45
- target[prop] = arguments[i][prop];
46
- }
47
- }
48
-
49
- return target;
50
- }
51
-
52
- var div = typeof document != "undefined" && document.createElement("div");
53
-
54
- return extend(buster, {
55
- bind: function (obj, methOrProp) {
56
- var method = typeof methOrProp == "string" ? obj[methOrProp] : methOrProp;
57
- var args = Array.prototype.slice.call(arguments, 2);
58
-
59
- return function () {
60
- var allArgs = args.concat(Array.prototype.slice.call(arguments));
61
- return method.apply(obj, allArgs);
62
- };
63
- },
64
-
65
- create: (function () {
66
- function F() {}
67
-
68
- return function create(object) {
69
- F.prototype = object;
70
- return new F();
71
- }
72
- }()),
73
-
74
- extend: extend,
75
-
76
- nextTick: function (callback) {
77
- if (typeof process != "undefined" && process.nextTick) {
78
- return process.nextTick(callback);
79
- }
80
-
81
- setTimeout(callback, 0);
82
- },
83
-
84
- functionName: function (func) {
85
- if (!func) return "";
86
- if (func.displayName) return func.displayName;
87
- if (func.name) return func.name;
88
-
89
- var matches = func.toString().match(/function\s+([^\(]+)/m);
90
- return matches && matches[1] || "";
91
- },
92
-
93
- isNode: function (obj) {
94
- if (!div) return false;
95
-
96
- try {
97
- obj.appendChild(div);
98
- obj.removeChild(div);
99
- } catch (e) {
100
- return false;
101
- }
102
-
103
- return true;
104
- },
105
-
106
- isElement: function (obj) {
107
- return obj && buster.isNode(obj) && obj.nodeType === 1;
108
- }
109
- });
110
- }(buster || {}, setTimeout));
111
-
112
- if (typeof module == "object" && typeof require == "function") {
113
- module.exports = buster;
114
- buster.eventEmitter = require("./buster-event-emitter");
115
-
116
- Object.defineProperty(buster, "defineVersionGetter", {
117
- get: function () {
118
- return require("./define-version-getter");
119
- }
120
- });
121
- }
122
-
123
-
124
- if (typeof require != "undefined") {
125
- buster = require("buster-core");
126
- }
127
-
128
- buster.format = buster.format || {};
129
- buster.format.excludeConstructors = ["Object", /^.$/];
130
- buster.format.quoteStrings = true;
131
-
132
- buster.format.ascii = (function () {
133
- function keys(object) {
134
- var k = Object.keys && Object.keys(object) || [];
135
-
136
- if (k.length == 0) {
137
- for (var prop in object) {
138
- if (object.hasOwnProperty(prop)) {
139
- k.push(prop);
140
- }
141
- }
142
- }
143
-
144
- return k.sort();
145
- }
146
-
147
- function isCircular(object, objects) {
148
- if (typeof object != "object") {
149
- return false;
150
- }
151
-
152
- for (var i = 0, l = objects.length; i < l; ++i) {
153
- if (objects[i] === object) {
154
- return true;
155
- }
156
- }
157
-
158
- return false;
159
- }
160
-
161
- function ascii(object, processed, indent) {
162
- if (typeof object == "string") {
163
- var quote = typeof this.quoteStrings != "boolean" || this.quoteStrings;
164
- return processed || quote ? '"' + object + '"' : object;
165
- }
166
-
167
- if (typeof object == "function" && !(object instanceof RegExp)) {
168
- return ascii.func(object);
169
- }
170
-
171
- processed = processed || [];
172
-
173
- if (isCircular(object, processed)) {
174
- return "[Circular]";
175
- }
176
-
177
- if (Object.prototype.toString.call(object) == "[object Array]") {
178
- return ascii.array(object);
179
- }
180
-
181
- if (!object) {
182
- return "" + object;
183
- }
184
-
185
- if (buster.isElement(object)) {
186
- return ascii.element(object);
187
- }
188
-
189
- if (object.toString !== Object.prototype.toString) {
190
- return object.toString();
191
- }
192
-
193
- return ascii.object.call(this, object, processed, indent);
194
- }
195
-
196
- ascii.func = function (func) {
197
- return "function " + buster.functionName(func) + "() {}";
198
- };
199
-
200
- ascii.array = function (array, processed) {
201
- processed = processed || [];
202
- processed.push(array);
203
- var pieces = [];
204
-
205
- for (var i = 0, l = array.length; i < l; ++i) {
206
- pieces.push(ascii(array[i], processed));
207
- }
208
-
209
- return "[" + pieces.join(", ") + "]";
210
- };
211
-
212
- ascii.object = function (object, processed, indent) {
213
- processed = processed || [];
214
- processed.push(object);
215
- indent = indent || 0;
216
- var pieces = [], properties = keys(object), prop, str, obj;
217
- var is = "";
218
- var length = 3;
219
-
220
- for (var i = 0, l = indent; i < l; ++i) {
221
- is += " ";
222
- }
223
-
224
- for (i = 0, l = properties.length; i < l; ++i) {
225
- prop = properties[i];
226
- obj = object[prop];
227
-
228
- if (isCircular(obj, processed)) {
229
- str = "[Circular]";
230
- } else {
231
- str = ascii.call(this, obj, processed, indent + 2);
232
- }
233
-
234
- str = (/\s/.test(prop) ? '"' + prop + '"' : prop) + ": " + str;
235
- length += str.length;
236
- pieces.push(str);
237
- }
238
-
239
- var cons = ascii.constructorName.call(this, object);
240
- var prefix = cons ? "[" + cons + "] " : ""
241
-
242
- return (length + indent) > 80 ?
243
- prefix + "{\n " + is + pieces.join(",\n " + is) + "\n" + is + "}" :
244
- prefix + "{ " + pieces.join(", ") + " }";
245
- };
246
-
247
- ascii.element = function (element) {
248
- var tagName = element.tagName.toLowerCase();
249
- var attrs = element.attributes, attribute, pairs = [], attrName;
250
-
251
- for (var i = 0, l = attrs.length; i < l; ++i) {
252
- attribute = attrs.item(i);
253
- attrName = attribute.nodeName.toLowerCase().replace("html:", "");
254
-
255
- if (attrName == "contenteditable" && attribute.nodeValue == "inherit") {
256
- continue;
257
- }
258
-
259
- if (!!attribute.nodeValue) {
260
- pairs.push(attrName + "=\"" + attribute.nodeValue + "\"");
261
- }
262
- }
263
-
264
- var formatted = "<" + tagName + (pairs.length > 0 ? " " : "");
265
- var content = element.innerHTML;
266
-
267
- if (content.length > 20) {
268
- content = content.substr(0, 20) + "[...]";
269
- }
270
-
271
- var res = formatted + pairs.join(" ") + ">" + content + "</" + tagName + ">";
272
-
273
- return res.replace(/ contentEditable="inherit"/, "");
274
- };
275
-
276
- ascii.constructorName = function (object) {
277
- var name = buster.functionName(object && object.constructor);
278
- var excludes = this.excludeConstructors || buster.format.excludeConstructors || [];
279
-
280
- for (var i = 0, l = excludes.length; i < l; ++i) {
281
- if (typeof excludes[i] == "string" && excludes[i] == name) {
282
- return "";
283
- } else if (excludes[i].test && excludes[i].test(name)) {
284
- return "";
285
- }
286
- }
287
-
288
- return name;
289
- };
290
-
291
- return ascii;
292
- }());
293
-
294
- if (typeof module != "undefined") {
295
- module.exports = buster.format;
296
- }
297
- /*jslint eqeqeq: false, onevar: false, forin: true, nomen: false, regexp: false, plusplus: false*/
298
- /*global module, require, __dirname, document*/
299
- /**
300
- * Sinon core utilities. For internal use only.
301
- *
302
- * @author Christian Johansen (christian@cjohansen.no)
303
- * @license BSD
304
- *
305
- * Copyright (c) 2010-2011 Christian Johansen
306
- */
307
-
308
- var sinon = (function (buster) {
309
- var div = typeof document != "undefined" && document.createElement("div");
310
- var hasOwn = Object.prototype.hasOwnProperty;
311
-
312
- function isDOMNode(obj) {
313
- var success = false;
314
-
315
- try {
316
- obj.appendChild(div);
317
- success = div.parentNode == obj;
318
- } catch (e) {
319
- return false;
320
- } finally {
321
- try {
322
- obj.removeChild(div);
323
- } catch (e) {
324
- // Remove failed, not much we can do about that
325
- }
326
- }
327
-
328
- return success;
329
- }
330
-
331
- function isElement(obj) {
332
- return div && obj && obj.nodeType === 1 && isDOMNode(obj);
333
- }
334
-
335
- function mirrorProperties(target, source) {
336
- for (var prop in source) {
337
- if (!hasOwn.call(target, prop)) {
338
- target[prop] = source[prop];
339
- }
340
- }
341
- }
342
-
343
- var sinon = {
344
- wrapMethod: function wrapMethod(object, property, method) {
345
- if (!object) {
346
- throw new TypeError("Should wrap property of object");
347
- }
348
-
349
- if (typeof method != "function") {
350
- throw new TypeError("Method wrapper should be function");
351
- }
352
-
353
- var wrappedMethod = object[property];
354
- var type = typeof wrappedMethod;
355
-
356
- if (type != "function") {
357
- throw new TypeError("Attempted to wrap " + type + " property " +
358
- property + " as function");
359
- }
360
-
361
- if (wrappedMethod.restore && wrappedMethod.restore.sinon) {
362
- throw new TypeError("Attempted to wrap " + property + " which is already wrapped");
363
- }
364
-
365
- if (wrappedMethod.calledBefore) {
366
- var verb = !!wrappedMethod.returns ? "stubbed" : "spied on";
367
- throw new TypeError("Attempted to wrap " + property + " which is already " + verb);
368
- }
369
-
370
- // IE 8 does not support hasOwnProperty on the window object.
371
- var owned = hasOwn.call(object, property);
372
- object[property] = method;
373
- method.displayName = property;
374
-
375
- method.restore = function () {
376
- if(owned) {
377
- object[property] = wrappedMethod;
378
- } else {
379
- delete object[property];
380
- }
381
- };
382
-
383
- method.restore.sinon = true;
384
- mirrorProperties(method, wrappedMethod);
385
-
386
- return method;
387
- },
388
-
389
- extend: function extend(target) {
390
- for (var i = 1, l = arguments.length; i < l; i += 1) {
391
- for (var prop in arguments[i]) {
392
- if (arguments[i].hasOwnProperty(prop)) {
393
- target[prop] = arguments[i][prop];
394
- }
395
-
396
- // DONT ENUM bug, only care about toString
397
- if (arguments[i].hasOwnProperty("toString") &&
398
- arguments[i].toString != target.toString) {
399
- target.toString = arguments[i].toString;
400
- }
401
- }
402
- }
403
-
404
- return target;
405
- },
406
-
407
- create: function create(proto) {
408
- var F = function () {};
409
- F.prototype = proto;
410
- return new F();
411
- },
412
-
413
- deepEqual: function deepEqual(a, b) {
414
- if (typeof a != "object" || typeof b != "object") {
415
- return a === b;
416
- }
417
-
418
- if (isElement(a) || isElement(b)) {
419
- return a === b;
420
- }
421
-
422
- if (a === b) {
423
- return true;
424
- }
425
-
426
- var aString = Object.prototype.toString.call(a);
427
- if (aString != Object.prototype.toString.call(b)) {
428
- return false;
429
- }
430
-
431
- if (aString == "[object Array]") {
432
- if (a.length !== b.length) {
433
- return false;
434
- }
435
-
436
- for (var i = 0, l = a.length; i < l; i += 1) {
437
- if (!deepEqual(a[i], b[i])) {
438
- return false;
439
- }
440
- }
441
-
442
- return true;
443
- }
444
-
445
- var prop, aLength = 0, bLength = 0;
446
-
447
- for (prop in a) {
448
- aLength += 1;
449
-
450
- if (!deepEqual(a[prop], b[prop])) {
451
- return false;
452
- }
453
- }
454
-
455
- for (prop in b) {
456
- bLength += 1;
457
- }
458
-
459
- if (aLength != bLength) {
460
- return false;
461
- }
462
-
463
- return true;
464
- },
465
-
466
- functionName: function functionName(func) {
467
- var name = func.displayName || func.name;
468
-
469
- // Use function decomposition as a last resort to get function
470
- // name. Does not rely on function decomposition to work - if it
471
- // doesn't debugging will be slightly less informative
472
- // (i.e. toString will say 'spy' rather than 'myFunc').
473
- if (!name) {
474
- var matches = func.toString().match(/function ([^\s\(]+)/);
475
- name = matches && matches[1];
476
- }
477
-
478
- return name;
479
- },
480
-
481
- functionToString: function toString() {
482
- if (this.getCall && this.callCount) {
483
- var thisValue, prop, i = this.callCount;
484
-
485
- while (i--) {
486
- thisValue = this.getCall(i).thisValue;
487
-
488
- for (prop in thisValue) {
489
- if (thisValue[prop] === this) {
490
- return prop;
491
- }
492
- }
493
- }
494
- }
495
-
496
- return this.displayName || "sinon fake";
497
- },
498
-
499
- getConfig: function (custom) {
500
- var config = {};
501
- custom = custom || {};
502
- var defaults = sinon.defaultConfig;
503
-
504
- for (var prop in defaults) {
505
- if (defaults.hasOwnProperty(prop)) {
506
- config[prop] = custom.hasOwnProperty(prop) ? custom[prop] : defaults[prop];
507
- }
508
- }
509
-
510
- return config;
511
- },
512
-
513
- format: function (val) {
514
- return "" + val;
515
- },
516
-
517
- defaultConfig: {
518
- injectIntoThis: true,
519
- injectInto: null,
520
- properties: ["spy", "stub", "mock", "clock", "server", "requests"],
521
- useFakeTimers: true,
522
- useFakeServer: true
523
- },
524
-
525
- timesInWords: function timesInWords(count) {
526
- return count == 1 && "once" ||
527
- count == 2 && "twice" ||
528
- count == 3 && "thrice" ||
529
- (count || 0) + " times";
530
- },
531
-
532
- calledInOrder: function (spies) {
533
- for (var i = 1, l = spies.length; i < l; i++) {
534
- if (!spies[i - 1].calledBefore(spies[i])) {
535
- return false;
536
- }
537
- }
538
-
539
- return true;
540
- },
541
-
542
- orderByFirstCall: function (spies) {
543
- return spies.sort(function (a, b) {
544
- // uuid, won't ever be equal
545
- var aCall = a.getCall(0);
546
- var bCall = b.getCall(0);
547
- var aId = aCall && aCall.callId || -1;
548
- var bId = bCall && bCall.callId || -1;
549
-
550
- return aId < bId ? -1 : 1;
551
- });
552
- },
553
-
554
- log: function () {},
555
-
556
- logError: function (label, err) {
557
- var msg = label + " threw exception: "
558
- sinon.log(msg + "[" + err.name + "] " + err.message);
559
- if (err.stack) { sinon.log(err.stack); }
560
-
561
- setTimeout(function () {
562
- err.message = msg + err.message;
563
- throw err;
564
- }, 0);
565
- }
566
- };
567
-
568
- var isNode = typeof module == "object" && typeof require == "function";
569
-
570
- if (isNode) {
571
- try {
572
- buster = { format: require("buster-format") };
573
- } catch (e) {}
574
- module.exports = sinon;
575
- module.exports.spy = require("./sinon/spy");
576
- module.exports.stub = require("./sinon/stub");
577
- module.exports.mock = require("./sinon/mock");
578
- module.exports.collection = require("./sinon/collection");
579
- module.exports.assert = require("./sinon/assert");
580
- module.exports.sandbox = require("./sinon/sandbox");
581
- module.exports.test = require("./sinon/test");
582
- module.exports.testCase = require("./sinon/test_case");
583
- module.exports.assert = require("./sinon/assert");
584
- }
585
-
586
- if (buster) {
587
- var formatter = sinon.create(buster.format);
588
- formatter.quoteStrings = false;
589
- sinon.format = function () {
590
- return formatter.ascii.apply(formatter, arguments);
591
- };
592
- } else if (isNode) {
593
- try {
594
- var util = require("util");
595
- sinon.format = function (value) {
596
- return typeof value == "object" ? util.inspect(value) : value;
597
- };
598
- } catch (e) {
599
- /* Node, but no util module - would be very old, but better safe than
600
- sorry */
601
- }
602
- }
603
-
604
- return sinon;
605
- }(typeof buster == "object" && buster));
606
-
607
- /* @depend ../sinon.js */
608
- /*jslint eqeqeq: false, onevar: false, plusplus: false*/
609
- /*global module, require, sinon*/
610
- /**
611
- * Spy functions
612
- *
613
- * @author Christian Johansen (christian@cjohansen.no)
614
- * @license BSD
615
- *
616
- * Copyright (c) 2010-2011 Christian Johansen
617
- */
618
-
619
- (function (sinon) {
620
- var commonJSModule = typeof module == "object" && typeof require == "function";
621
- var spyCall;
622
- var callId = 0;
623
- var push = [].push;
624
- var slice = Array.prototype.slice;
625
-
626
- if (!sinon && commonJSModule) {
627
- sinon = require("../sinon");
628
- }
629
-
630
- if (!sinon) {
631
- return;
632
- }
633
-
634
- function spy(object, property) {
635
- if (!property && typeof object == "function") {
636
- return spy.create(object);
637
- }
638
-
639
- if (!object || !property) {
640
- return spy.create(function () {});
641
- }
642
-
643
- var method = object[property];
644
- return sinon.wrapMethod(object, property, spy.create(method));
645
- }
646
-
647
- sinon.extend(spy, (function () {
648
-
649
- function delegateToCalls(api, method, matchAny, actual, notCalled) {
650
- api[method] = function () {
651
- if (!this.called) {
652
- if (notCalled) {
653
- return notCalled.apply(this, arguments);
654
- }
655
- return false;
656
- }
657
-
658
- var currentCall;
659
- var matches = 0;
660
-
661
- for (var i = 0, l = this.callCount; i < l; i += 1) {
662
- currentCall = this.getCall(i);
663
-
664
- if (currentCall[actual || method].apply(currentCall, arguments)) {
665
- matches += 1;
666
-
667
- if (matchAny) {
668
- return true;
669
- }
670
- }
671
- }
672
-
673
- return matches === this.callCount;
674
- };
675
- }
676
-
677
- function matchingFake(fakes, args, strict) {
678
- if (!fakes) {
679
- return;
680
- }
681
-
682
- var alen = args.length;
683
-
684
- for (var i = 0, l = fakes.length; i < l; i++) {
685
- if (fakes[i].matches(args, strict)) {
686
- return fakes[i];
687
- }
688
- }
689
- }
690
-
691
- var uuid = 0;
692
-
693
- // Public API
694
- var spyApi = {
695
- reset: function () {
696
- this.called = false;
697
- this.calledOnce = false;
698
- this.calledTwice = false;
699
- this.calledThrice = false;
700
- this.callCount = 0;
701
- this.firstCall = null;
702
- this.secondCall = null;
703
- this.thirdCall = null;
704
- this.lastCall = null;
705
- this.args = [];
706
- this.returnValues = [];
707
- this.thisValues = [];
708
- this.exceptions = [];
709
- this.callIds = [];
710
- },
711
-
712
- create: function create(func) {
713
- var name;
714
-
715
- if (typeof func != "function") {
716
- func = function () {};
717
- } else {
718
- name = sinon.functionName(func);
719
- }
720
-
721
- function proxy() {
722
- return proxy.invoke(func, this, slice.call(arguments));
723
- }
724
-
725
- sinon.extend(proxy, spy);
726
- delete proxy.create;
727
- sinon.extend(proxy, func);
728
-
729
- proxy.reset();
730
- proxy.prototype = func.prototype;
731
- proxy.displayName = name || "spy";
732
- proxy.toString = sinon.functionToString;
733
- proxy._create = sinon.spy.create;
734
- proxy.id = "spy#" + uuid++;
735
-
736
- return proxy;
737
- },
738
-
739
- invoke: function invoke(func, thisValue, args) {
740
- var matching = matchingFake(this.fakes, args);
741
- var exception, returnValue;
742
- this.called = true;
743
- this.callCount += 1;
744
- this.calledOnce = this.callCount == 1;
745
- this.calledTwice = this.callCount == 2;
746
- this.calledThrice = this.callCount == 3;
747
- push.call(this.thisValues, thisValue);
748
- push.call(this.args, args);
749
- push.call(this.callIds, callId++);
750
-
751
- try {
752
- if (matching) {
753
- returnValue = matching.invoke(func, thisValue, args);
754
- } else {
755
- returnValue = (this.func || func).apply(thisValue, args);
756
- }
757
- } catch (e) {
758
- push.call(this.returnValues, undefined);
759
- exception = e;
760
- throw e;
761
- } finally {
762
- push.call(this.exceptions, exception);
763
- }
764
-
765
- push.call(this.returnValues, returnValue);
766
-
767
- this.firstCall = this.getCall(0);
768
- this.secondCall = this.getCall(1);
769
- this.thirdCall = this.getCall(2);
770
- this.lastCall = this.getCall(this.callCount - 1);
771
-
772
- return returnValue;
773
- },
774
-
775
- getCall: function getCall(i) {
776
- if (i < 0 || i >= this.callCount) {
777
- return null;
778
- }
779
-
780
- return spyCall.create(this, this.thisValues[i], this.args[i],
781
- this.returnValues[i], this.exceptions[i],
782
- this.callIds[i]);
783
- },
784
-
785
- calledBefore: function calledBefore(spyFn) {
786
- if (!this.called) {
787
- return false;
788
- }
789
-
790
- if (!spyFn.called) {
791
- return true;
792
- }
793
-
794
- return this.callIds[0] < spyFn.callIds[spyFn.callIds.length - 1];
795
- },
796
-
797
- calledAfter: function calledAfter(spyFn) {
798
- if (!this.called || !spyFn.called) {
799
- return false;
800
- }
801
-
802
- return this.callIds[this.callCount - 1] > spyFn.callIds[spyFn.callCount - 1];
803
- },
804
-
805
- withArgs: function () {
806
- var args = slice.call(arguments);
807
-
808
- if (this.fakes) {
809
- var match = matchingFake(this.fakes, args, true);
810
-
811
- if (match) {
812
- return match;
813
- }
814
- } else {
815
- this.fakes = [];
816
- }
817
-
818
- var original = this;
819
- var fake = this._create();
820
- fake.matchingAguments = args;
821
- push.call(this.fakes, fake);
822
-
823
- fake.withArgs = function () {
824
- return original.withArgs.apply(original, arguments);
825
- };
826
-
827
- return fake;
828
- },
829
-
830
- matches: function (args, strict) {
831
- var margs = this.matchingAguments;
832
-
833
- if (margs.length <= args.length &&
834
- sinon.deepEqual(margs, args.slice(0, margs.length))) {
835
- return !strict || margs.length == args.length;
836
- }
837
- },
838
-
839
- printf: function (format) {
840
- var spy = this;
841
- var args = slice.call(arguments, 1);
842
- var formatter;
843
-
844
- return (format || "").replace(/%(.)/g, function (match, specifyer) {
845
- formatter = spyApi.formatters[specifyer];
846
-
847
- if (typeof formatter == "function") {
848
- return formatter.call(null, spy, args);
849
- } else if (!isNaN(parseInt(specifyer), 10)) {
850
- return sinon.format(args[specifyer - 1]);
851
- }
852
-
853
- return "%" + specifyer;
854
- });
855
- }
856
- };
857
-
858
- delegateToCalls(spyApi, "calledOn", true);
859
- delegateToCalls(spyApi, "alwaysCalledOn", false, "calledOn");
860
- delegateToCalls(spyApi, "calledWith", true);
861
- delegateToCalls(spyApi, "alwaysCalledWith", false, "calledWith");
862
- delegateToCalls(spyApi, "calledWithExactly", true);
863
- delegateToCalls(spyApi, "alwaysCalledWithExactly", false, "calledWithExactly");
864
- delegateToCalls(spyApi, "neverCalledWith", false, "notCalledWith",
865
- function () { return true; });
866
- delegateToCalls(spyApi, "threw", true);
867
- delegateToCalls(spyApi, "alwaysThrew", false, "threw");
868
- delegateToCalls(spyApi, "returned", true);
869
- delegateToCalls(spyApi, "alwaysReturned", false, "returned");
870
- delegateToCalls(spyApi, "calledWithNew", true);
871
- delegateToCalls(spyApi, "alwaysCalledWithNew", false, "calledWithNew");
872
- delegateToCalls(spyApi, "callArg", false, "callArgWith", function () {
873
- throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
874
- });
875
- spyApi.callArgWith = spyApi.callArg;
876
- delegateToCalls(spyApi, "yield", false, "yield", function () {
877
- throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
878
- });
879
- // "invokeCallback" is an alias for "yield" since "yield" is invalid in strict mode.
880
- spyApi.invokeCallback = spyApi.yield;
881
- delegateToCalls(spyApi, "yieldTo", false, "yieldTo", function (property) {
882
- throw new Error(this.toString() + " cannot yield to '" + property +
883
- "' since it was not yet invoked.");
884
- });
885
-
886
- spyApi.formatters = {
887
- "c": function (spy) {
888
- return sinon.timesInWords(spy.callCount);
889
- },
890
-
891
- "n": function (spy) {
892
- return spy.toString();
893
- },
894
-
895
- "C": function (spy) {
896
- var calls = [];
897
-
898
- for (var i = 0, l = spy.callCount; i < l; ++i) {
899
- push.call(calls, " " + spy.getCall(i).toString());
900
- }
901
-
902
- return calls.length > 0 ? "\n" + calls.join("\n") : "";
903
- },
904
-
905
- "t": function (spy) {
906
- var objects = [];
907
-
908
- for (var i = 0, l = spy.callCount; i < l; ++i) {
909
- push.call(objects, sinon.format(spy.thisValues[i]));
910
- }
911
-
912
- return objects.join(", ");
913
- },
914
-
915
- "*": function (spy, args) {
916
- return args.join(", ");
917
- }
918
- };
919
-
920
- return spyApi;
921
- }()));
922
-
923
- spyCall = (function () {
924
-
925
- function throwYieldError(proxy, text, args) {
926
- var msg = sinon.functionName(proxy) + text;
927
- if (args.length) {
928
- msg += " Received [" + slice.call(args).join(", ") + "]";
929
- }
930
- throw new Error(msg);
931
- }
932
-
933
- return {
934
- create: function create(spy, thisValue, args, returnValue, exception, id) {
935
- var proxyCall = sinon.create(spyCall);
936
- delete proxyCall.create;
937
- proxyCall.proxy = spy;
938
- proxyCall.thisValue = thisValue;
939
- proxyCall.args = args;
940
- proxyCall.returnValue = returnValue;
941
- proxyCall.exception = exception;
942
- proxyCall.callId = typeof id == "number" && id || callId++;
943
-
944
- return proxyCall;
945
- },
946
-
947
- calledOn: function calledOn(thisValue) {
948
- return this.thisValue === thisValue;
949
- },
950
-
951
- calledWith: function calledWith() {
952
- for (var i = 0, l = arguments.length; i < l; i += 1) {
953
- if (!sinon.deepEqual(arguments[i], this.args[i])) {
954
- return false;
955
- }
956
- }
957
-
958
- return true;
959
- },
960
-
961
- calledWithExactly: function calledWithExactly() {
962
- return arguments.length == this.args.length &&
963
- this.calledWith.apply(this, arguments);
964
- },
965
-
966
- notCalledWith: function notCalledWith() {
967
- for (var i = 0, l = arguments.length; i < l; i += 1) {
968
- if (!sinon.deepEqual(arguments[i], this.args[i])) {
969
- return true;
970
- }
971
- }
972
- return false;
973
- },
974
-
975
- returned: function returned(value) {
976
- return this.returnValue === value;
977
- },
978
-
979
- threw: function threw(error) {
980
- if (typeof error == "undefined" || !this.exception) {
981
- return !!this.exception;
982
- }
983
-
984
- if (typeof error == "string") {
985
- return this.exception.name == error;
986
- }
987
-
988
- return this.exception === error;
989
- },
990
-
991
- calledWithNew: function calledWithNew(thisValue) {
992
- return this.thisValue instanceof this.proxy;
993
- },
994
-
995
- calledBefore: function (other) {
996
- return this.callId < other.callId;
997
- },
998
-
999
- calledAfter: function (other) {
1000
- return this.callId > other.callId;
1001
- },
1002
-
1003
- callArg: function (pos) {
1004
- this.args[pos]();
1005
- },
1006
-
1007
- callArgWith: function (pos) {
1008
- var args = slice.call(arguments, 1);
1009
- this.args[pos].apply(null, args);
1010
- },
1011
-
1012
- "yield": function () {
1013
- var args = this.args;
1014
- for (var i = 0, l = args.length; i < l; ++i) {
1015
- if (typeof args[i] === "function") {
1016
- args[i].apply(null, slice.call(arguments));
1017
- return;
1018
- }
1019
- }
1020
- throwYieldError(this.proxy, " cannot yield since no callback was passed.", args);
1021
- },
1022
-
1023
- yieldTo: function (prop) {
1024
- var args = this.args;
1025
- for (var i = 0, l = args.length; i < l; ++i) {
1026
- if (args[i] && typeof args[i][prop] === "function") {
1027
- args[i][prop].apply(null, slice.call(arguments, 1));
1028
- return;
1029
- }
1030
- }
1031
- throwYieldError(this.proxy, " cannot yield to '" + prop +
1032
- "' since no callback was passed.", args);
1033
- },
1034
-
1035
- toString: function () {
1036
- var callStr = this.proxy.toString() + "(";
1037
- var args = [];
1038
-
1039
- for (var i = 0, l = this.args.length; i < l; ++i) {
1040
- push.call(args, sinon.format(this.args[i]));
1041
- }
1042
-
1043
- callStr = callStr + args.join(", ") + ")";
1044
-
1045
- if (typeof this.returnValue != "undefined") {
1046
- callStr += " => " + sinon.format(this.returnValue);
1047
- }
1048
-
1049
- if (this.exception) {
1050
- callStr += " !" + this.exception.name;
1051
-
1052
- if (this.exception.message) {
1053
- callStr += "(" + this.exception.message + ")";
1054
- }
1055
- }
1056
-
1057
- return callStr;
1058
- }
1059
- };
1060
- }());
1061
-
1062
- spy.spyCall = spyCall;
1063
-
1064
- // This steps outside the module sandbox and will be removed
1065
- sinon.spyCall = spyCall;
1066
-
1067
- if (commonJSModule) {
1068
- module.exports = spy;
1069
- } else {
1070
- sinon.spy = spy;
1071
- }
1072
- }(typeof sinon == "object" && sinon || null));
1073
-
1074
- /**
1075
- * @depend ../sinon.js
1076
- * @depend spy.js
1077
- */
1078
- /*jslint eqeqeq: false, onevar: false*/
1079
- /*global module, require, sinon*/
1080
- /**
1081
- * Stub functions
1082
- *
1083
- * @author Christian Johansen (christian@cjohansen.no)
1084
- * @license BSD
1085
- *
1086
- * Copyright (c) 2010-2011 Christian Johansen
1087
- */
1088
-
1089
- (function (sinon) {
1090
- var commonJSModule = typeof module == "object" && typeof require == "function";
1091
-
1092
- if (!sinon && commonJSModule) {
1093
- sinon = require("../sinon");
1094
- }
1095
-
1096
- if (!sinon) {
1097
- return;
1098
- }
1099
-
1100
- function stub(object, property, func) {
1101
- if (!!func && typeof func != "function") {
1102
- throw new TypeError("Custom stub should be function");
1103
- }
1104
-
1105
- var wrapper;
1106
-
1107
- if (func) {
1108
- wrapper = sinon.spy && sinon.spy.create ? sinon.spy.create(func) : func;
1109
- } else {
1110
- wrapper = stub.create();
1111
- }
1112
-
1113
- if (!object && !property) {
1114
- return sinon.stub.create();
1115
- }
1116
-
1117
- if (!property && !!object && typeof object == "object") {
1118
- for (var prop in object) {
1119
- if (typeof object[prop] === "function") {
1120
- stub(object, prop);
1121
- }
1122
- }
1123
-
1124
- return object;
1125
- }
1126
-
1127
- return sinon.wrapMethod(object, property, wrapper);
1128
- }
1129
-
1130
- function getCallback(stub, args) {
1131
- if (stub.callArgAt < 0) {
1132
- for (var i = 0, l = args.length; i < l; ++i) {
1133
- if (!stub.callArgProp && typeof args[i] == "function") {
1134
- return args[i];
1135
- }
1136
-
1137
- if (stub.callArgProp && args[i] &&
1138
- typeof args[i][stub.callArgProp] == "function") {
1139
- return args[i][stub.callArgProp];
1140
- }
1141
- }
1142
-
1143
- return null;
1144
- }
1145
-
1146
- return args[stub.callArgAt];
1147
- }
1148
-
1149
- var join = Array.prototype.join;
1150
-
1151
- function getCallbackError(stub, func, args) {
1152
- if (stub.callArgAt < 0) {
1153
- var msg;
1154
-
1155
- if (stub.callArgProp) {
1156
- msg = sinon.functionName(stub) +
1157
- " expected to yield to '" + stub.callArgProp +
1158
- "', but no object with such a property was passed."
1159
- } else {
1160
- msg = sinon.functionName(stub) +
1161
- " expected to yield, but no callback was passed."
1162
- }
1163
-
1164
- if (args.length > 0) {
1165
- msg += " Received [" + join.call(args, ", ") + "]";
1166
- }
1167
-
1168
- return msg;
1169
- }
1170
-
1171
- return "argument at index " + stub.callArgAt + " is not a function: " + func;
1172
- }
1173
-
1174
- function callCallback(stub, args) {
1175
- if (typeof stub.callArgAt == "number") {
1176
- var func = getCallback(stub, args);
1177
-
1178
- if (typeof func != "function") {
1179
- throw new TypeError(getCallbackError(stub, func, args));
1180
- }
1181
-
1182
- func.apply(null, stub.callbackArguments);
1183
- }
1184
- }
1185
-
1186
- var uuid = 0;
1187
-
1188
- sinon.extend(stub, (function () {
1189
- var slice = Array.prototype.slice;
1190
-
1191
- function throwsException(error, message) {
1192
- if (typeof error == "string") {
1193
- this.exception = new Error(message || "");
1194
- this.exception.name = error;
1195
- } else if (!error) {
1196
- this.exception = new Error("Error");
1197
- } else {
1198
- this.exception = error;
1199
- }
1200
-
1201
- return this;
1202
- }
1203
-
1204
- return {
1205
- create: function create() {
1206
- var functionStub = function () {
1207
- if (functionStub.exception) {
1208
- throw functionStub.exception;
1209
- } else if (typeof functionStub.returnArgAt == 'number') {
1210
- return arguments[functionStub.returnArgAt];
1211
- }
1212
-
1213
- callCallback(functionStub, arguments);
1214
-
1215
- return functionStub.returnValue;
1216
- };
1217
-
1218
- functionStub.id = "stub#" + uuid++;
1219
- var orig = functionStub;
1220
- functionStub = sinon.spy.create(functionStub);
1221
- functionStub.func = orig;
1222
-
1223
- sinon.extend(functionStub, stub);
1224
- functionStub._create = sinon.stub.create;
1225
- functionStub.displayName = "stub";
1226
- functionStub.toString = sinon.functionToString;
1227
-
1228
- return functionStub;
1229
- },
1230
-
1231
- returns: function returns(value) {
1232
- this.returnValue = value;
1233
-
1234
- return this;
1235
- },
1236
-
1237
- returnsArg: function returnsArg(pos) {
1238
- if (typeof pos != "number") {
1239
- throw new TypeError("argument index is not number");
1240
- }
1241
-
1242
- this.returnArgAt = pos;
1243
-
1244
- return this;
1245
- },
1246
-
1247
- "throws": throwsException,
1248
- throwsException: throwsException,
1249
-
1250
- callsArg: function callsArg(pos) {
1251
- if (typeof pos != "number") {
1252
- throw new TypeError("argument index is not number");
1253
- }
1254
-
1255
- this.callArgAt = pos;
1256
- this.callbackArguments = [];
1257
-
1258
- return this;
1259
- },
1260
-
1261
- callsArgWith: function callsArgWith(pos) {
1262
- if (typeof pos != "number") {
1263
- throw new TypeError("argument index is not number");
1264
- }
1265
-
1266
- this.callArgAt = pos;
1267
- this.callbackArguments = slice.call(arguments, 1);
1268
-
1269
- return this;
1270
- },
1271
-
1272
- yields: function () {
1273
- this.callArgAt = -1;
1274
- this.callbackArguments = slice.call(arguments, 0);
1275
-
1276
- return this;
1277
- },
1278
-
1279
- yieldsTo: function (prop) {
1280
- this.callArgAt = -1;
1281
- this.callArgProp = prop;
1282
- this.callbackArguments = slice.call(arguments, 1);
1283
-
1284
- return this;
1285
- }
1286
- };
1287
- }()));
1288
-
1289
- if (commonJSModule) {
1290
- module.exports = stub;
1291
- } else {
1292
- sinon.stub = stub;
1293
- }
1294
- }(typeof sinon == "object" && sinon || null));
1295
-
1296
- /**
1297
- * @depend ../sinon.js
1298
- * @depend stub.js
1299
- */
1300
- /*jslint eqeqeq: false, onevar: false, nomen: false*/
1301
- /*global module, require, sinon*/
1302
- /**
1303
- * Mock functions.
1304
- *
1305
- * @author Christian Johansen (christian@cjohansen.no)
1306
- * @license BSD
1307
- *
1308
- * Copyright (c) 2010-2011 Christian Johansen
1309
- */
1310
-
1311
- (function (sinon) {
1312
- var commonJSModule = typeof module == "object" && typeof require == "function";
1313
- var push = [].push;
1314
-
1315
- if (!sinon && commonJSModule) {
1316
- sinon = require("../sinon");
1317
- }
1318
-
1319
- if (!sinon) {
1320
- return;
1321
- }
1322
-
1323
- function mock(object) {
1324
- if (!object) {
1325
- return sinon.expectation.create("Anonymous mock");
1326
- }
1327
-
1328
- return mock.create(object);
1329
- }
1330
-
1331
- sinon.mock = mock;
1332
-
1333
- sinon.extend(mock, (function () {
1334
- function each(collection, callback) {
1335
- if (!collection) {
1336
- return;
1337
- }
1338
-
1339
- for (var i = 0, l = collection.length; i < l; i += 1) {
1340
- callback(collection[i]);
1341
- }
1342
- }
1343
-
1344
- return {
1345
- create: function create(object) {
1346
- if (!object) {
1347
- throw new TypeError("object is null");
1348
- }
1349
-
1350
- var mockObject = sinon.extend({}, mock);
1351
- mockObject.object = object;
1352
- delete mockObject.create;
1353
-
1354
- return mockObject;
1355
- },
1356
-
1357
- expects: function expects(method) {
1358
- if (!method) {
1359
- throw new TypeError("method is falsy");
1360
- }
1361
-
1362
- if (!this.expectations) {
1363
- this.expectations = {};
1364
- this.proxies = [];
1365
- }
1366
-
1367
- if (!this.expectations[method]) {
1368
- this.expectations[method] = [];
1369
- var mockObject = this;
1370
-
1371
- sinon.wrapMethod(this.object, method, function () {
1372
- return mockObject.invokeMethod(method, this, arguments);
1373
- });
1374
-
1375
- push.call(this.proxies, method);
1376
- }
1377
-
1378
- var expectation = sinon.expectation.create(method);
1379
- push.call(this.expectations[method], expectation);
1380
-
1381
- return expectation;
1382
- },
1383
-
1384
- restore: function restore() {
1385
- var object = this.object;
1386
-
1387
- each(this.proxies, function (proxy) {
1388
- if (typeof object[proxy].restore == "function") {
1389
- object[proxy].restore();
1390
- }
1391
- });
1392
- },
1393
-
1394
- verify: function verify() {
1395
- var expectations = this.expectations || {};
1396
- var messages = [], met = [];
1397
-
1398
- each(this.proxies, function (proxy) {
1399
- each(expectations[proxy], function (expectation) {
1400
- if (!expectation.met()) {
1401
- push.call(messages, expectation.toString());
1402
- } else {
1403
- push.call(met, expectation.toString());
1404
- }
1405
- });
1406
- });
1407
-
1408
- this.restore();
1409
-
1410
- if (messages.length > 0) {
1411
- sinon.expectation.fail(messages.concat(met).join("\n"));
1412
- }
1413
-
1414
- return true;
1415
- },
1416
-
1417
- invokeMethod: function invokeMethod(method, thisValue, args) {
1418
- var expectations = this.expectations && this.expectations[method];
1419
- var length = expectations && expectations.length || 0;
1420
-
1421
- for (var i = 0; i < length; i += 1) {
1422
- if (!expectations[i].met() &&
1423
- expectations[i].allowsCall(thisValue, args)) {
1424
- return expectations[i].apply(thisValue, args);
1425
- }
1426
- }
1427
-
1428
- var messages = [];
1429
-
1430
- for (i = 0; i < length; i += 1) {
1431
- push.call(messages, " " + expectations[i].toString());
1432
- }
1433
-
1434
- messages.unshift("Unexpected call: " + sinon.spyCall.toString.call({
1435
- proxy: method,
1436
- args: args
1437
- }));
1438
-
1439
- sinon.expectation.fail(messages.join("\n"));
1440
- }
1441
- };
1442
- }()));
1443
-
1444
- var times = sinon.timesInWords;
1445
-
1446
- sinon.expectation = (function () {
1447
- var slice = Array.prototype.slice;
1448
- var _invoke = sinon.spy.invoke;
1449
-
1450
- function callCountInWords(callCount) {
1451
- if (callCount == 0) {
1452
- return "never called";
1453
- } else {
1454
- return "called " + times(callCount);
1455
- }
1456
- }
1457
-
1458
- function expectedCallCountInWords(expectation) {
1459
- var min = expectation.minCalls;
1460
- var max = expectation.maxCalls;
1461
-
1462
- if (typeof min == "number" && typeof max == "number") {
1463
- var str = times(min);
1464
-
1465
- if (min != max) {
1466
- str = "at least " + str + " and at most " + times(max);
1467
- }
1468
-
1469
- return str;
1470
- }
1471
-
1472
- if (typeof min == "number") {
1473
- return "at least " + times(min);
1474
- }
1475
-
1476
- return "at most " + times(max);
1477
- }
1478
-
1479
- function receivedMinCalls(expectation) {
1480
- var hasMinLimit = typeof expectation.minCalls == "number";
1481
- return !hasMinLimit || expectation.callCount >= expectation.minCalls;
1482
- }
1483
-
1484
- function receivedMaxCalls(expectation) {
1485
- if (typeof expectation.maxCalls != "number") {
1486
- return false;
1487
- }
1488
-
1489
- return expectation.callCount == expectation.maxCalls;
1490
- }
1491
-
1492
- return {
1493
- minCalls: 1,
1494
- maxCalls: 1,
1495
-
1496
- create: function create(methodName) {
1497
- var expectation = sinon.extend(sinon.stub.create(), sinon.expectation);
1498
- delete expectation.create;
1499
- expectation.method = methodName;
1500
-
1501
- return expectation;
1502
- },
1503
-
1504
- invoke: function invoke(func, thisValue, args) {
1505
- this.verifyCallAllowed(thisValue, args);
1506
-
1507
- return _invoke.apply(this, arguments);
1508
- },
1509
-
1510
- atLeast: function atLeast(num) {
1511
- if (typeof num != "number") {
1512
- throw new TypeError("'" + num + "' is not number");
1513
- }
1514
-
1515
- if (!this.limitsSet) {
1516
- this.maxCalls = null;
1517
- this.limitsSet = true;
1518
- }
1519
-
1520
- this.minCalls = num;
1521
-
1522
- return this;
1523
- },
1524
-
1525
- atMost: function atMost(num) {
1526
- if (typeof num != "number") {
1527
- throw new TypeError("'" + num + "' is not number");
1528
- }
1529
-
1530
- if (!this.limitsSet) {
1531
- this.minCalls = null;
1532
- this.limitsSet = true;
1533
- }
1534
-
1535
- this.maxCalls = num;
1536
-
1537
- return this;
1538
- },
1539
-
1540
- never: function never() {
1541
- return this.exactly(0);
1542
- },
1543
-
1544
- once: function once() {
1545
- return this.exactly(1);
1546
- },
1547
-
1548
- twice: function twice() {
1549
- return this.exactly(2);
1550
- },
1551
-
1552
- thrice: function thrice() {
1553
- return this.exactly(3);
1554
- },
1555
-
1556
- exactly: function exactly(num) {
1557
- if (typeof num != "number") {
1558
- throw new TypeError("'" + num + "' is not a number");
1559
- }
1560
-
1561
- this.atLeast(num);
1562
- return this.atMost(num);
1563
- },
1564
-
1565
- met: function met() {
1566
- return !this.failed && receivedMinCalls(this);
1567
- },
1568
-
1569
- verifyCallAllowed: function verifyCallAllowed(thisValue, args) {
1570
- if (receivedMaxCalls(this)) {
1571
- this.failed = true;
1572
- sinon.expectation.fail(this.method + " already called " + times(this.maxCalls));
1573
- }
1574
-
1575
- if ("expectedThis" in this && this.expectedThis !== thisValue) {
1576
- sinon.expectation.fail(this.method + " called with " + thisValue + " as thisValue, expected " +
1577
- this.expectedThis);
1578
- }
1579
-
1580
- if (!("expectedArguments" in this)) {
1581
- return;
1582
- }
1583
-
1584
- if (!args || args.length === 0) {
1585
- sinon.expectation.fail(this.method + " received no arguments, expected " +
1586
- this.expectedArguments.join());
1587
- }
1588
-
1589
- if (args.length < this.expectedArguments.length) {
1590
- sinon.expectation.fail(this.method + " received too few arguments (" + args.join() +
1591
- "), expected " + this.expectedArguments.join());
1592
- }
1593
-
1594
- if (this.expectsExactArgCount &&
1595
- args.length != this.expectedArguments.length) {
1596
- sinon.expectation.fail(this.method + " received too many arguments (" + args.join() +
1597
- "), expected " + this.expectedArguments.join());
1598
- }
1599
-
1600
- for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
1601
- if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
1602
- sinon.expectation.fail(this.method + " received wrong arguments (" + args.join() +
1603
- "), expected " + this.expectedArguments.join());
1604
- }
1605
- }
1606
- },
1607
-
1608
- allowsCall: function allowsCall(thisValue, args) {
1609
- if (this.met()) {
1610
- return false;
1611
- }
1612
-
1613
- if ("expectedThis" in this && this.expectedThis !== thisValue) {
1614
- return false;
1615
- }
1616
-
1617
- if (!("expectedArguments" in this)) {
1618
- return true;
1619
- }
1620
-
1621
- args = args || [];
1622
-
1623
- if (args.length < this.expectedArguments.length) {
1624
- return false;
1625
- }
1626
-
1627
- if (this.expectsExactArgCount &&
1628
- args.length != this.expectedArguments.length) {
1629
- return false;
1630
- }
1631
-
1632
- for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
1633
- if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
1634
- return false;
1635
- }
1636
- }
1637
-
1638
- return true;
1639
- },
1640
-
1641
- withArgs: function withArgs() {
1642
- this.expectedArguments = slice.call(arguments);
1643
- return this;
1644
- },
1645
-
1646
- withExactArgs: function withExactArgs() {
1647
- this.withArgs.apply(this, arguments);
1648
- this.expectsExactArgCount = true;
1649
- return this;
1650
- },
1651
-
1652
- on: function on(thisValue) {
1653
- this.expectedThis = thisValue;
1654
- return this;
1655
- },
1656
-
1657
- toString: function () {
1658
- var args = (this.expectedArguments || []).slice();
1659
-
1660
- if (!this.expectsExactArgCount) {
1661
- push.call(args, "[...]");
1662
- }
1663
-
1664
- var callStr = sinon.spyCall.toString.call({
1665
- proxy: this.method, args: args
1666
- });
1667
-
1668
- var message = callStr.replace(", [...", "[, ...") + " " +
1669
- expectedCallCountInWords(this);
1670
-
1671
- if (this.met()) {
1672
- return "Expectation met: " + message;
1673
- }
1674
-
1675
- return "Expected " + message + " (" +
1676
- callCountInWords(this.callCount) + ")";
1677
- },
1678
-
1679
- verify: function verify() {
1680
- if (!this.met()) {
1681
- sinon.expectation.fail(this.toString());
1682
- }
1683
-
1684
- return true;
1685
- },
1686
-
1687
- fail: function (message) {
1688
- var exception = new Error(message);
1689
- exception.name = "ExpectationError";
1690
-
1691
- throw exception;
1692
- }
1693
- };
1694
- }());
1695
-
1696
- if (commonJSModule) {
1697
- module.exports = mock;
1698
- } else {
1699
- sinon.mock = mock;
1700
- }
1701
- }(typeof sinon == "object" && sinon || null));
1702
-
1703
- /**
1704
- * @depend ../sinon.js
1705
- * @depend stub.js
1706
- * @depend mock.js
1707
- */
1708
- /*jslint eqeqeq: false, onevar: false, forin: true*/
1709
- /*global module, require, sinon*/
1710
- /**
1711
- * Collections of stubs, spies and mocks.
1712
- *
1713
- * @author Christian Johansen (christian@cjohansen.no)
1714
- * @license BSD
1715
- *
1716
- * Copyright (c) 2010-2011 Christian Johansen
1717
- */
1718
-
1719
- (function (sinon) {
1720
- var commonJSModule = typeof module == "object" && typeof require == "function";
1721
- var push = [].push;
1722
-
1723
- if (!sinon && commonJSModule) {
1724
- sinon = require("../sinon");
1725
- }
1726
-
1727
- if (!sinon) {
1728
- return;
1729
- }
1730
-
1731
- function getFakes(fakeCollection) {
1732
- if (!fakeCollection.fakes) {
1733
- fakeCollection.fakes = [];
1734
- }
1735
-
1736
- return fakeCollection.fakes;
1737
- }
1738
-
1739
- function each(fakeCollection, method) {
1740
- var fakes = getFakes(fakeCollection);
1741
-
1742
- for (var i = 0, l = fakes.length; i < l; i += 1) {
1743
- if (typeof fakes[i][method] == "function") {
1744
- fakes[i][method]();
1745
- }
1746
- }
1747
- }
1748
-
1749
- function compact(fakeCollection) {
1750
- var fakes = getFakes(fakeCollection);
1751
- var i = 0;
1752
- while (i < fakes.length) {
1753
- fakes.splice(i, 1);
1754
- }
1755
- }
1756
-
1757
- var collection = {
1758
- verify: function resolve() {
1759
- each(this, "verify");
1760
- },
1761
-
1762
- restore: function restore() {
1763
- each(this, "restore");
1764
- compact(this);
1765
- },
1766
-
1767
- verifyAndRestore: function verifyAndRestore() {
1768
- var exception;
1769
-
1770
- try {
1771
- this.verify();
1772
- } catch (e) {
1773
- exception = e;
1774
- }
1775
-
1776
- this.restore();
1777
-
1778
- if (exception) {
1779
- throw exception;
1780
- }
1781
- },
1782
-
1783
- add: function add(fake) {
1784
- push.call(getFakes(this), fake);
1785
- return fake;
1786
- },
1787
-
1788
- spy: function spy() {
1789
- return this.add(sinon.spy.apply(sinon, arguments));
1790
- },
1791
-
1792
- stub: function stub(object, property, value) {
1793
- if (property) {
1794
- var original = object[property];
1795
-
1796
- if (typeof original != "function") {
1797
- if (!object.hasOwnProperty(property)) {
1798
- throw new TypeError("Cannot stub non-existent own property " + property);
1799
- }
1800
-
1801
- object[property] = value;
1802
-
1803
- return this.add({
1804
- restore: function () {
1805
- object[property] = original;
1806
- }
1807
- });
1808
- }
1809
- }
1810
-
1811
- return this.add(sinon.stub.apply(sinon, arguments));
1812
- },
1813
-
1814
- mock: function mock() {
1815
- return this.add(sinon.mock.apply(sinon, arguments));
1816
- },
1817
-
1818
- inject: function inject(obj) {
1819
- var col = this;
1820
-
1821
- obj.spy = function () {
1822
- return col.spy.apply(col, arguments);
1823
- };
1824
-
1825
- obj.stub = function () {
1826
- return col.stub.apply(col, arguments);
1827
- };
1828
-
1829
- obj.mock = function () {
1830
- return col.mock.apply(col, arguments);
1831
- };
1832
-
1833
- return obj;
1834
- }
1835
- };
1836
-
1837
- if (commonJSModule) {
1838
- module.exports = collection;
1839
- } else {
1840
- sinon.collection = collection;
1841
- }
1842
- }(typeof sinon == "object" && sinon || null));
1843
-
1844
- /*jslint eqeqeq: false, plusplus: false, evil: true, onevar: false, browser: true, forin: false*/
1845
- /*global module, require, window*/
1846
- /**
1847
- * Fake timer API
1848
- * setTimeout
1849
- * setInterval
1850
- * clearTimeout
1851
- * clearInterval
1852
- * tick
1853
- * reset
1854
- * Date
1855
- *
1856
- * Inspired by jsUnitMockTimeOut from JsUnit
1857
- *
1858
- * @author Christian Johansen (christian@cjohansen.no)
1859
- * @license BSD
1860
- *
1861
- * Copyright (c) 2010-2011 Christian Johansen
1862
- */
1863
-
1864
- if (typeof sinon == "undefined") {
1865
- var sinon = {};
1866
- }
1867
-
1868
- (function (global) {
1869
- var id = 1;
1870
-
1871
- function addTimer(args, recurring) {
1872
- if (args.length === 0) {
1873
- throw new Error("Function requires at least 1 parameter");
1874
- }
1875
-
1876
- var toId = id++;
1877
- var delay = args[1] || 0;
1878
-
1879
- if (!this.timeouts) {
1880
- this.timeouts = {};
1881
- }
1882
-
1883
- this.timeouts[toId] = {
1884
- id: toId,
1885
- func: args[0],
1886
- callAt: this.now + delay
1887
- };
1888
-
1889
- if (recurring === true) {
1890
- this.timeouts[toId].interval = delay;
1891
- }
1892
-
1893
- return toId;
1894
- }
1895
-
1896
- function parseTime(str) {
1897
- if (!str) {
1898
- return 0;
1899
- }
1900
-
1901
- var strings = str.split(":");
1902
- var l = strings.length, i = l;
1903
- var ms = 0, parsed;
1904
-
1905
- if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) {
1906
- throw new Error("tick only understands numbers and 'h:m:s'");
1907
- }
1908
-
1909
- while (i--) {
1910
- parsed = parseInt(strings[i], 10);
1911
-
1912
- if (parsed >= 60) {
1913
- throw new Error("Invalid time " + str);
1914
- }
1915
-
1916
- ms += parsed * Math.pow(60, (l - i - 1));
1917
- }
1918
-
1919
- return ms * 1000;
1920
- }
1921
-
1922
- function createObject(object) {
1923
- var newObject;
1924
-
1925
- if (Object.create) {
1926
- newObject = Object.create(object);
1927
- } else {
1928
- var F = function () {};
1929
- F.prototype = object;
1930
- newObject = new F();
1931
- }
1932
-
1933
- newObject.Date.clock = newObject;
1934
- return newObject;
1935
- }
1936
-
1937
- sinon.clock = {
1938
- now: 0,
1939
-
1940
- create: function create(now) {
1941
- var clock = createObject(this);
1942
-
1943
- if (typeof now == "number") {
1944
- clock.now = now;
1945
- }
1946
-
1947
- if (!!now && typeof now == "object") {
1948
- throw new TypeError("now should be milliseconds since UNIX epoch");
1949
- }
1950
-
1951
- return clock;
1952
- },
1953
-
1954
- setTimeout: function setTimeout(callback, timeout) {
1955
- return addTimer.call(this, arguments, false);
1956
- },
1957
-
1958
- clearTimeout: function clearTimeout(timerId) {
1959
- if (!this.timeouts) {
1960
- this.timeouts = [];
1961
- }
1962
-
1963
- delete this.timeouts[timerId];
1964
- },
1965
-
1966
- setInterval: function setInterval(callback, timeout) {
1967
- return addTimer.call(this, arguments, true);
1968
- },
1969
-
1970
- clearInterval: function clearInterval(timerId) {
1971
- this.clearTimeout(timerId);
1972
- },
1973
-
1974
- tick: function tick(ms) {
1975
- ms = typeof ms == "number" ? ms : parseTime(ms);
1976
- var tickFrom = this.now, tickTo = this.now + ms, previous = this.now;
1977
- var timer = this.firstTimerInRange(tickFrom, tickTo);
1978
-
1979
- var firstException;
1980
- while (timer && tickFrom <= tickTo) {
1981
- if (this.timeouts[timer.id]) {
1982
- tickFrom = this.now = timer.callAt;
1983
- try {
1984
- this.callTimer(timer);
1985
- } catch (e) {
1986
- firstException = firstException || e;
1987
- }
1988
- }
1989
-
1990
- timer = this.firstTimerInRange(previous, tickTo);
1991
- previous = tickFrom;
1992
- }
1993
-
1994
- this.now = tickTo;
1995
-
1996
- if (firstException) {
1997
- throw firstException;
1998
- }
1999
- },
2000
-
2001
- firstTimerInRange: function (from, to) {
2002
- var timer, smallest, originalTimer;
2003
-
2004
- for (var id in this.timeouts) {
2005
- if (this.timeouts.hasOwnProperty(id)) {
2006
- if (this.timeouts[id].callAt < from || this.timeouts[id].callAt > to) {
2007
- continue;
2008
- }
2009
-
2010
- if (!smallest || this.timeouts[id].callAt < smallest) {
2011
- originalTimer = this.timeouts[id];
2012
- smallest = this.timeouts[id].callAt;
2013
-
2014
- timer = {
2015
- func: this.timeouts[id].func,
2016
- callAt: this.timeouts[id].callAt,
2017
- interval: this.timeouts[id].interval,
2018
- id: this.timeouts[id].id
2019
- };
2020
- }
2021
- }
2022
- }
2023
-
2024
- return timer || null;
2025
- },
2026
-
2027
- callTimer: function (timer) {
2028
- try {
2029
- if (typeof timer.func == "function") {
2030
- timer.func.call(null);
2031
- } else {
2032
- eval(timer.func);
2033
- }
2034
- } catch (e) {
2035
- var exception = e;
2036
- }
2037
-
2038
- if (!this.timeouts[timer.id]) {
2039
- if (exception) {
2040
- throw exception;
2041
- }
2042
- return;
2043
- }
2044
-
2045
- if (typeof timer.interval == "number") {
2046
- this.timeouts[timer.id].callAt += timer.interval;
2047
- } else {
2048
- delete this.timeouts[timer.id];
2049
- }
2050
-
2051
- if (exception) {
2052
- throw exception;
2053
- }
2054
- },
2055
-
2056
- reset: function reset() {
2057
- this.timeouts = {};
2058
- },
2059
-
2060
- Date: (function () {
2061
- var NativeDate = Date;
2062
-
2063
- function ClockDate(year, month, date, hour, minute, second, ms) {
2064
- // Defensive and verbose to avoid potential harm in passing
2065
- // explicit undefined when user does not pass argument
2066
- switch (arguments.length) {
2067
- case 0:
2068
- return new NativeDate(ClockDate.clock.now);
2069
- case 1:
2070
- return new NativeDate(year);
2071
- case 2:
2072
- return new NativeDate(year, month);
2073
- case 3:
2074
- return new NativeDate(year, month, date);
2075
- case 4:
2076
- return new NativeDate(year, month, date, hour);
2077
- case 5:
2078
- return new NativeDate(year, month, date, hour, minute);
2079
- case 6:
2080
- return new NativeDate(year, month, date, hour, minute, second);
2081
- default:
2082
- return new NativeDate(year, month, date, hour, minute, second, ms);
2083
- }
2084
- }
2085
-
2086
- return mirrorDateProperties(ClockDate, NativeDate);
2087
- }())
2088
- };
2089
-
2090
- function mirrorDateProperties(target, source) {
2091
- if (source.now) {
2092
- target.now = function now() {
2093
- return target.clock.now;
2094
- };
2095
- } else {
2096
- delete target.now;
2097
- }
2098
-
2099
- if (source.toSource) {
2100
- target.toSource = function toSource() {
2101
- return source.toSource();
2102
- };
2103
- } else {
2104
- delete target.toSource;
2105
- }
2106
-
2107
- target.toString = function toString() {
2108
- return source.toString();
2109
- };
2110
-
2111
- target.prototype = source.prototype;
2112
- target.parse = source.parse;
2113
- target.UTC = source.UTC;
2114
- target.prototype.toUTCString = source.prototype.toUTCString;
2115
- return target;
2116
- }
2117
-
2118
- var methods = ["Date", "setTimeout", "setInterval",
2119
- "clearTimeout", "clearInterval"];
2120
-
2121
- function restore() {
2122
- var method;
2123
-
2124
- for (var i = 0, l = this.methods.length; i < l; i++) {
2125
- method = this.methods[i];
2126
- global[method] = this["_" + method];
2127
- }
2128
- }
2129
-
2130
- function stubGlobal(method, clock) {
2131
- clock["_" + method] = global[method];
2132
-
2133
- if (method == "Date") {
2134
- var date = mirrorDateProperties(clock[method], global[method]);
2135
- global[method] = date;
2136
- } else {
2137
- global[method] = function () {
2138
- return clock[method].apply(clock, arguments);
2139
- };
2140
-
2141
- for (var prop in clock[method]) {
2142
- if (clock[method].hasOwnProperty(prop)) {
2143
- global[method][prop] = clock[method][prop];
2144
- }
2145
- }
2146
- }
2147
-
2148
- global[method].clock = clock;
2149
- }
2150
-
2151
- sinon.useFakeTimers = function useFakeTimers(now) {
2152
- var clock = sinon.clock.create(now);
2153
- clock.restore = restore;
2154
- clock.methods = Array.prototype.slice.call(arguments,
2155
- typeof now == "number" ? 1 : 0);
2156
-
2157
- if (clock.methods.length === 0) {
2158
- clock.methods = methods;
2159
- }
2160
-
2161
- for (var i = 0, l = clock.methods.length; i < l; i++) {
2162
- stubGlobal(clock.methods[i], clock);
2163
- }
2164
-
2165
- return clock;
2166
- };
2167
- }(typeof global != "undefined" ? global : this));
2168
-
2169
- sinon.timers = {
2170
- setTimeout: setTimeout,
2171
- clearTimeout: clearTimeout,
2172
- setInterval: setInterval,
2173
- clearInterval: clearInterval,
2174
- Date: Date
2175
- };
2176
-
2177
- if (typeof module == "object" && typeof require == "function") {
2178
- module.exports = sinon;
2179
- }
2180
-
2181
- /*jslint eqeqeq: false, onevar: false*/
2182
- /*global sinon, module, require, ActiveXObject, XMLHttpRequest, DOMParser*/
2183
- /**
2184
- * Minimal Event interface implementation
2185
- *
2186
- * Original implementation by Sven Fuchs: https://gist.github.com/995028
2187
- * Modifications and tests by Christian Johansen.
2188
- *
2189
- * @author Sven Fuchs (svenfuchs@artweb-design.de)
2190
- * @author Christian Johansen (christian@cjohansen.no)
2191
- * @license BSD
2192
- *
2193
- * Copyright (c) 2011 Sven Fuchs, Christian Johansen
2194
- */
2195
-
2196
- if (typeof sinon == "undefined") {
2197
- this.sinon = {};
2198
- }
2199
-
2200
- (function () {
2201
- var push = [].push;
2202
-
2203
- sinon.Event = function Event(type, bubbles, cancelable) {
2204
- this.initEvent(type, bubbles, cancelable);
2205
- };
2206
-
2207
- sinon.Event.prototype = {
2208
- initEvent: function(type, bubbles, cancelable) {
2209
- this.type = type;
2210
- this.bubbles = bubbles;
2211
- this.cancelable = cancelable;
2212
- },
2213
-
2214
- stopPropagation: function () {},
2215
-
2216
- preventDefault: function () {
2217
- this.defaultPrevented = true;
2218
- }
2219
- };
2220
-
2221
- sinon.EventTarget = {
2222
- addEventListener: function addEventListener(event, listener, useCapture) {
2223
- this.eventListeners = this.eventListeners || {};
2224
- this.eventListeners[event] = this.eventListeners[event] || [];
2225
- push.call(this.eventListeners[event], listener);
2226
- },
2227
-
2228
- removeEventListener: function removeEventListener(event, listener, useCapture) {
2229
- var listeners = this.eventListeners && this.eventListeners[event] || [];
2230
-
2231
- for (var i = 0, l = listeners.length; i < l; ++i) {
2232
- if (listeners[i] == listener) {
2233
- return listeners.splice(i, 1);
2234
- }
2235
- }
2236
- },
2237
-
2238
- dispatchEvent: function dispatchEvent(event) {
2239
- var type = event.type;
2240
- var listeners = this.eventListeners && this.eventListeners[type] || [];
2241
-
2242
- for (var i = 0; i < listeners.length; i++) {
2243
- if (typeof listeners[i] == "function") {
2244
- listeners[i].call(this, event);
2245
- } else {
2246
- listeners[i].handleEvent(event);
2247
- }
2248
- }
2249
-
2250
- return !!event.defaultPrevented;
2251
- }
2252
- };
2253
- }());
2254
-
2255
- /**
2256
- * @depend event.js
2257
- */
2258
- /*jslint eqeqeq: false, onevar: false*/
2259
- /*global sinon, module, require, ActiveXObject, XMLHttpRequest, DOMParser*/
2260
- /**
2261
- * Fake XMLHttpRequest object
2262
- *
2263
- * @author Christian Johansen (christian@cjohansen.no)
2264
- * @license BSD
2265
- *
2266
- * Copyright (c) 2010-2011 Christian Johansen
2267
- */
2268
-
2269
- if (typeof sinon == "undefined") {
2270
- this.sinon = {};
2271
- }
2272
- sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
2273
-
2274
- // wrapper for global
2275
- (function(global) {
2276
- var xhr = sinon.xhr;
2277
- xhr.GlobalXMLHttpRequest = global.XMLHttpRequest;
2278
- xhr.GlobalActiveXObject = global.ActiveXObject;
2279
- xhr.supportsActiveX = typeof xhr.GlobalActiveXObject != "undefined";
2280
- xhr.supportsXHR = typeof xhr.GlobalXMLHttpRequest != "undefined";
2281
- xhr.workingXHR = xhr.supportsXHR ? xhr.GlobalXMLHttpRequest : xhr.supportsActiveX
2282
- ? function() { return new xhr.GlobalActiveXObject("MSXML2.XMLHTTP.3.0") } : false;
2283
-
2284
- /*jsl:ignore*/
2285
- var unsafeHeaders = {
2286
- "Accept-Charset": true,
2287
- "Accept-Encoding": true,
2288
- "Connection": true,
2289
- "Content-Length": true,
2290
- "Cookie": true,
2291
- "Cookie2": true,
2292
- "Content-Transfer-Encoding": true,
2293
- "Date": true,
2294
- "Expect": true,
2295
- "Host": true,
2296
- "Keep-Alive": true,
2297
- "Referer": true,
2298
- "TE": true,
2299
- "Trailer": true,
2300
- "Transfer-Encoding": true,
2301
- "Upgrade": true,
2302
- "User-Agent": true,
2303
- "Via": true
2304
- };
2305
- /*jsl:end*/
2306
-
2307
- function FakeXMLHttpRequest() {
2308
- this.readyState = FakeXMLHttpRequest.UNSENT;
2309
- this.requestHeaders = {};
2310
- this.requestBody = null;
2311
- this.status = 0;
2312
- this.statusText = "";
2313
-
2314
- if (typeof FakeXMLHttpRequest.onCreate == "function") {
2315
- FakeXMLHttpRequest.onCreate(this);
2316
- }
2317
- }
2318
-
2319
- function verifyState(xhr) {
2320
- if (xhr.readyState !== FakeXMLHttpRequest.OPENED) {
2321
- throw new Error("INVALID_STATE_ERR");
2322
- }
2323
-
2324
- if (xhr.sendFlag) {
2325
- throw new Error("INVALID_STATE_ERR");
2326
- }
2327
- }
2328
-
2329
- // filtering to enable a white-list version of Sinon FakeXhr,
2330
- // where whitelisted requests are passed through to real XHR
2331
- function each(collection, callback) {
2332
- if (!collection) return;
2333
- for (var i = 0, l = collection.length; i < l; i += 1) {
2334
- callback(collection[i]);
2335
- }
2336
- }
2337
- function some(collection, callback) {
2338
- for (var index = 0; index < collection.length; index++) {
2339
- if(callback(collection[index]) === true) return true;
2340
- };
2341
- return false;
2342
- }
2343
- // largest arity in XHR is 5 - XHR#open
2344
- var apply = function(obj,method,args) {
2345
- switch(args.length) {
2346
- case 0: return obj[method]();
2347
- case 1: return obj[method](args[0]);
2348
- case 2: return obj[method](args[0],args[1]);
2349
- case 3: return obj[method](args[0],args[1],args[2]);
2350
- case 4: return obj[method](args[0],args[1],args[2],args[3]);
2351
- case 5: return obj[method](args[0],args[1],args[2],args[3],args[4]);
2352
- };
2353
- };
2354
-
2355
- FakeXMLHttpRequest.filters = [];
2356
- FakeXMLHttpRequest.addFilter = function(fn) {
2357
- this.filters.push(fn)
2358
- };
2359
- var IE6Re = /MSIE 6/;
2360
- FakeXMLHttpRequest.defake = function(fakeXhr,xhrArgs) {
2361
- var xhr = new sinon.xhr.workingXHR();
2362
- each(["open","setRequestHeader","send","abort","getResponseHeader",
2363
- "getAllResponseHeaders","addEventListener","overrideMimeType","removeEventListener"],
2364
- function(method) {
2365
- fakeXhr[method] = function() {
2366
- return apply(xhr,method,arguments);
2367
- };
2368
- });
2369
-
2370
- var copyAttrs = function(args) {
2371
- each(args, function(attr) {
2372
- try {
2373
- fakeXhr[attr] = xhr[attr]
2374
- } catch(e) {
2375
- if(!IE6Re.test(navigator.userAgent)) throw e;
2376
- }
2377
- });
2378
- };
2379
-
2380
- var stateChange = function() {
2381
- fakeXhr.readyState = xhr.readyState;
2382
- if(xhr.readyState >= FakeXMLHttpRequest.HEADERS_RECEIVED) {
2383
- copyAttrs(["status","statusText"]);
2384
- }
2385
- if(xhr.readyState >= FakeXMLHttpRequest.LOADING) {
2386
- copyAttrs(["responseText"]);
2387
- }
2388
- if(xhr.readyState === FakeXMLHttpRequest.DONE) {
2389
- copyAttrs(["responseXML"]);
2390
- }
2391
- if(fakeXhr.onreadystatechange) fakeXhr.onreadystatechange.call(fakeXhr);
2392
- };
2393
- if(xhr.addEventListener) {
2394
- for(var event in fakeXhr.eventListeners) {
2395
- if(fakeXhr.eventListeners.hasOwnProperty(event)) {
2396
- each(fakeXhr.eventListeners[event],function(handler) {
2397
- xhr.addEventListener(event, handler);
2398
- });
2399
- }
2400
- }
2401
- xhr.addEventListener("readystatechange",stateChange);
2402
- } else {
2403
- xhr.onreadystatechange = stateChange;
2404
- }
2405
- apply(xhr,"open",xhrArgs);
2406
- };
2407
- FakeXMLHttpRequest.useFilters = false;
2408
-
2409
- function verifyRequestSent(xhr) {
2410
- if (xhr.readyState == FakeXMLHttpRequest.DONE) {
2411
- throw new Error("Request done");
2412
- }
2413
- }
2414
-
2415
- function verifyHeadersReceived(xhr) {
2416
- if (xhr.async && xhr.readyState != FakeXMLHttpRequest.HEADERS_RECEIVED) {
2417
- throw new Error("No headers received");
2418
- }
2419
- }
2420
-
2421
- function verifyResponseBodyType(body) {
2422
- if (typeof body != "string") {
2423
- var error = new Error("Attempted to respond to fake XMLHttpRequest with " +
2424
- body + ", which is not a string.");
2425
- error.name = "InvalidBodyException";
2426
- throw error;
2427
- }
2428
- }
2429
-
2430
- sinon.extend(FakeXMLHttpRequest.prototype, sinon.EventTarget, {
2431
- async: true,
2432
-
2433
- open: function open(method, url, async, username, password) {
2434
- this.method = method;
2435
- this.url = url;
2436
- this.async = typeof async == "boolean" ? async : true;
2437
- this.username = username;
2438
- this.password = password;
2439
- this.responseText = null;
2440
- this.responseXML = null;
2441
- this.requestHeaders = {};
2442
- this.sendFlag = false;
2443
- if(sinon.FakeXMLHttpRequest.useFilters === true) {
2444
- var xhrArgs = arguments;
2445
- var defake = some(FakeXMLHttpRequest.filters,function(filter) {
2446
- return filter.apply(this,xhrArgs)
2447
- });
2448
- if (defake) { sinon.FakeXMLHttpRequest.defake(this,arguments); }
2449
- } else {
2450
- this.readyStateChange(FakeXMLHttpRequest.OPENED);
2451
- }
2452
- },
2453
-
2454
- readyStateChange: function readyStateChange(state) {
2455
- this.readyState = state;
2456
-
2457
- if (typeof this.onreadystatechange == "function") {
2458
- try {
2459
- this.onreadystatechange();
2460
- } catch (e) {
2461
- sinon.logError("Fake XHR onreadystatechange handler", e);
2462
- }
2463
- }
2464
-
2465
- this.dispatchEvent(new sinon.Event("readystatechange"));
2466
- },
2467
-
2468
- setRequestHeader: function setRequestHeader(header, value) {
2469
- verifyState(this);
2470
-
2471
- if (unsafeHeaders[header] || /^(Sec-|Proxy-)/.test(header)) {
2472
- throw new Error("Refused to set unsafe header \"" + header + "\"");
2473
- }
2474
-
2475
- if (this.requestHeaders[header]) {
2476
- this.requestHeaders[header] += "," + value;
2477
- } else {
2478
- this.requestHeaders[header] = value;
2479
- }
2480
- },
2481
-
2482
- // Helps testing
2483
- setResponseHeaders: function setResponseHeaders(headers) {
2484
- this.responseHeaders = {};
2485
-
2486
- for (var header in headers) {
2487
- if (headers.hasOwnProperty(header)) {
2488
- this.responseHeaders[header] = headers[header];
2489
- }
2490
- }
2491
-
2492
- if (this.async) {
2493
- this.readyStateChange(FakeXMLHttpRequest.HEADERS_RECEIVED);
2494
- }
2495
- },
2496
-
2497
- // Currently treats ALL data as a DOMString (i.e. no Document)
2498
- send: function send(data) {
2499
- verifyState(this);
2500
-
2501
- if (!/^(get|head)$/i.test(this.method)) {
2502
- if (this.requestHeaders["Content-Type"]) {
2503
- var value = this.requestHeaders["Content-Type"].split(";");
2504
- this.requestHeaders["Content-Type"] = value[0] + ";charset=utf-8";
2505
- } else {
2506
- this.requestHeaders["Content-Type"] = "text/plain;charset=utf-8";
2507
- }
2508
-
2509
- this.requestBody = data;
2510
- }
2511
-
2512
- this.errorFlag = false;
2513
- this.sendFlag = this.async;
2514
- this.readyStateChange(FakeXMLHttpRequest.OPENED);
2515
-
2516
- if (typeof this.onSend == "function") {
2517
- this.onSend(this);
2518
- }
2519
- },
2520
-
2521
- abort: function abort() {
2522
- this.aborted = true;
2523
- this.responseText = null;
2524
- this.errorFlag = true;
2525
- this.requestHeaders = {};
2526
-
2527
- if (this.readyState > sinon.FakeXMLHttpRequest.UNSENT && this.sendFlag) {
2528
- this.readyStateChange(sinon.FakeXMLHttpRequest.DONE);
2529
- this.sendFlag = false;
2530
- }
2531
-
2532
- this.readyState = sinon.FakeXMLHttpRequest.UNSENT;
2533
- },
2534
-
2535
- getResponseHeader: function getResponseHeader(header) {
2536
- if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
2537
- return null;
2538
- }
2539
-
2540
- if (/^Set-Cookie2?$/i.test(header)) {
2541
- return null;
2542
- }
2543
-
2544
- header = header.toLowerCase();
2545
-
2546
- for (var h in this.responseHeaders) {
2547
- if (h.toLowerCase() == header) {
2548
- return this.responseHeaders[h];
2549
- }
2550
- }
2551
-
2552
- return null;
2553
- },
2554
-
2555
- getAllResponseHeaders: function getAllResponseHeaders() {
2556
- if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
2557
- return "";
2558
- }
2559
-
2560
- var headers = "";
2561
-
2562
- for (var header in this.responseHeaders) {
2563
- if (this.responseHeaders.hasOwnProperty(header) &&
2564
- !/^Set-Cookie2?$/i.test(header)) {
2565
- headers += header + ": " + this.responseHeaders[header] + "\r\n";
2566
- }
2567
- }
2568
-
2569
- return headers;
2570
- },
2571
-
2572
- setResponseBody: function setResponseBody(body) {
2573
- verifyRequestSent(this);
2574
- verifyHeadersReceived(this);
2575
- verifyResponseBodyType(body);
2576
-
2577
- var chunkSize = this.chunkSize || 10;
2578
- var index = 0;
2579
- this.responseText = "";
2580
-
2581
- do {
2582
- if (this.async) {
2583
- this.readyStateChange(FakeXMLHttpRequest.LOADING);
2584
- }
2585
-
2586
- this.responseText += body.substring(index, index + chunkSize);
2587
- index += chunkSize;
2588
- } while (index < body.length);
2589
-
2590
- var type = this.getResponseHeader("Content-Type");
2591
-
2592
- if (this.responseText &&
2593
- (!type || /(text\/xml)|(application\/xml)|(\+xml)/.test(type))) {
2594
- try {
2595
- this.responseXML = FakeXMLHttpRequest.parseXML(this.responseText);
2596
- } catch (e) {
2597
- // Unable to parse XML - no biggie
2598
- }
2599
- }
2600
-
2601
- if (this.async) {
2602
- this.readyStateChange(FakeXMLHttpRequest.DONE);
2603
- } else {
2604
- this.readyState = FakeXMLHttpRequest.DONE;
2605
- }
2606
- },
2607
-
2608
- respond: function respond(status, headers, body) {
2609
- this.setResponseHeaders(headers || {});
2610
- this.status = typeof status == "number" ? status : 200;
2611
- this.statusText = FakeXMLHttpRequest.statusCodes[this.status];
2612
- this.setResponseBody(body || "");
2613
- }
2614
- });
2615
-
2616
- sinon.extend(FakeXMLHttpRequest, {
2617
- UNSENT: 0,
2618
- OPENED: 1,
2619
- HEADERS_RECEIVED: 2,
2620
- LOADING: 3,
2621
- DONE: 4
2622
- });
2623
-
2624
- // Borrowed from JSpec
2625
- FakeXMLHttpRequest.parseXML = function parseXML(text) {
2626
- var xmlDoc;
2627
-
2628
- if (typeof DOMParser != "undefined") {
2629
- var parser = new DOMParser();
2630
- xmlDoc = parser.parseFromString(text, "text/xml");
2631
- } else {
2632
- xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
2633
- xmlDoc.async = "false";
2634
- xmlDoc.loadXML(text);
2635
- }
2636
-
2637
- return xmlDoc;
2638
- };
2639
-
2640
- FakeXMLHttpRequest.statusCodes = {
2641
- 100: "Continue",
2642
- 101: "Switching Protocols",
2643
- 200: "OK",
2644
- 201: "Created",
2645
- 202: "Accepted",
2646
- 203: "Non-Authoritative Information",
2647
- 204: "No Content",
2648
- 205: "Reset Content",
2649
- 206: "Partial Content",
2650
- 300: "Multiple Choice",
2651
- 301: "Moved Permanently",
2652
- 302: "Found",
2653
- 303: "See Other",
2654
- 304: "Not Modified",
2655
- 305: "Use Proxy",
2656
- 307: "Temporary Redirect",
2657
- 400: "Bad Request",
2658
- 401: "Unauthorized",
2659
- 402: "Payment Required",
2660
- 403: "Forbidden",
2661
- 404: "Not Found",
2662
- 405: "Method Not Allowed",
2663
- 406: "Not Acceptable",
2664
- 407: "Proxy Authentication Required",
2665
- 408: "Request Timeout",
2666
- 409: "Conflict",
2667
- 410: "Gone",
2668
- 411: "Length Required",
2669
- 412: "Precondition Failed",
2670
- 413: "Request Entity Too Large",
2671
- 414: "Request-URI Too Long",
2672
- 415: "Unsupported Media Type",
2673
- 416: "Requested Range Not Satisfiable",
2674
- 417: "Expectation Failed",
2675
- 422: "Unprocessable Entity",
2676
- 500: "Internal Server Error",
2677
- 501: "Not Implemented",
2678
- 502: "Bad Gateway",
2679
- 503: "Service Unavailable",
2680
- 504: "Gateway Timeout",
2681
- 505: "HTTP Version Not Supported"
2682
- };
2683
-
2684
- sinon.useFakeXMLHttpRequest = function () {
2685
- sinon.FakeXMLHttpRequest.restore = function restore(keepOnCreate) {
2686
- if (xhr.supportsXHR) {
2687
- global.XMLHttpRequest = xhr.GlobalXMLHttpRequest;
2688
- }
2689
-
2690
- if (xhr.supportsActiveX) {
2691
- global.ActiveXObject = xhr.GlobalActiveXObject;
2692
- }
2693
-
2694
- delete sinon.FakeXMLHttpRequest.restore;
2695
-
2696
- if (keepOnCreate !== true) {
2697
- delete sinon.FakeXMLHttpRequest.onCreate;
2698
- }
2699
- };
2700
- if (xhr.supportsXHR) {
2701
- global.XMLHttpRequest = sinon.FakeXMLHttpRequest;
2702
- }
2703
-
2704
- if (xhr.supportsActiveX) {
2705
- global.ActiveXObject = function ActiveXObject(objId) {
2706
- if (objId == "Microsoft.XMLHTTP" || /^Msxml2\.XMLHTTP/i.test(objId)) {
2707
-
2708
- return new sinon.FakeXMLHttpRequest();
2709
- }
2710
-
2711
- return new xhr.GlobalActiveXObject(objId);
2712
- };
2713
- }
2714
-
2715
- return sinon.FakeXMLHttpRequest;
2716
- };
2717
-
2718
- sinon.FakeXMLHttpRequest = FakeXMLHttpRequest;
2719
- })(this);
2720
-
2721
- if (typeof module == "object" && typeof require == "function") {
2722
- module.exports = sinon;
2723
- }
2724
-
2725
- /**
2726
- * @depend fake_xml_http_request.js
2727
- */
2728
- /*jslint eqeqeq: false, onevar: false, regexp: false, plusplus: false*/
2729
- /*global module, require, window*/
2730
- /**
2731
- * The Sinon "server" mimics a web server that receives requests from
2732
- * sinon.FakeXMLHttpRequest and provides an API to respond to those requests,
2733
- * both synchronously and asynchronously. To respond synchronuously, canned
2734
- * answers have to be provided upfront.
2735
- *
2736
- * @author Christian Johansen (christian@cjohansen.no)
2737
- * @license BSD
2738
- *
2739
- * Copyright (c) 2010-2011 Christian Johansen
2740
- */
2741
-
2742
- if (typeof sinon == "undefined") {
2743
- var sinon = {};
2744
- }
2745
-
2746
- sinon.fakeServer = (function () {
2747
- var push = [].push;
2748
- function F() {}
2749
-
2750
- function create(proto) {
2751
- F.prototype = proto;
2752
- return new F();
2753
- }
2754
-
2755
- function responseArray(handler) {
2756
- var response = handler;
2757
-
2758
- if (Object.prototype.toString.call(handler) != "[object Array]") {
2759
- response = [200, {}, handler];
2760
- }
2761
-
2762
- if (typeof response[2] != "string") {
2763
- throw new TypeError("Fake server response body should be string, but was " +
2764
- typeof response[2]);
2765
- }
2766
-
2767
- return response;
2768
- }
2769
-
2770
- var wloc = window.location;
2771
- var rCurrLoc = new RegExp("^" + wloc.protocol + "//" + wloc.host);
2772
-
2773
- function matchOne(response, reqMethod, reqUrl) {
2774
- var rmeth = response.method;
2775
- var matchMethod = !rmeth || rmeth.toLowerCase() == reqMethod.toLowerCase();
2776
- var url = response.url;
2777
- var matchUrl = !url || url == reqUrl || (typeof url.test == "function" && url.test(reqUrl));
2778
-
2779
- return matchMethod && matchUrl;
2780
- }
2781
-
2782
- function match(response, request) {
2783
- var requestMethod = this.getHTTPMethod(request);
2784
- var requestUrl = request.url;
2785
-
2786
- if (!/^https?:\/\//.test(requestUrl) || rCurrLoc.test(requestUrl)) {
2787
- requestUrl = requestUrl.replace(rCurrLoc, "");
2788
- }
2789
-
2790
- if (matchOne(response, this.getHTTPMethod(request), requestUrl)) {
2791
- if (typeof response.response == "function") {
2792
- var ru = response.url;
2793
- var args = [request].concat(!ru ? [] : requestUrl.match(ru).slice(1));
2794
- return response.response.apply(response, args);
2795
- }
2796
-
2797
- return true;
2798
- }
2799
-
2800
- return false;
2801
- }
2802
-
2803
- return {
2804
- create: function () {
2805
- var server = create(this);
2806
- this.xhr = sinon.useFakeXMLHttpRequest();
2807
- server.requests = [];
2808
-
2809
- this.xhr.onCreate = function (xhrObj) {
2810
- server.addRequest(xhrObj);
2811
- };
2812
-
2813
- return server;
2814
- },
2815
-
2816
- addRequest: function addRequest(xhrObj) {
2817
- var server = this;
2818
- push.call(this.requests, xhrObj);
2819
-
2820
- xhrObj.onSend = function () {
2821
- server.handleRequest(this);
2822
- };
2823
-
2824
- if (this.autoRespond && !this.responding) {
2825
- setTimeout(function () {
2826
- server.responding = false;
2827
- server.respond();
2828
- }, this.autoRespondAfter || 10);
2829
-
2830
- this.responding = true;
2831
- }
2832
- },
2833
-
2834
- getHTTPMethod: function getHTTPMethod(request) {
2835
- if (this.fakeHTTPMethods && /post/i.test(request.method)) {
2836
- var matches = (request.requestBody || "").match(/_method=([^\b;]+)/);
2837
- return !!matches ? matches[1] : request.method;
2838
- }
2839
-
2840
- return request.method;
2841
- },
2842
-
2843
- handleRequest: function handleRequest(xhr) {
2844
- if (xhr.async) {
2845
- if (!this.queue) {
2846
- this.queue = [];
2847
- }
2848
-
2849
- push.call(this.queue, xhr);
2850
- } else {
2851
- this.processRequest(xhr);
2852
- }
2853
- },
2854
-
2855
- respondWith: function respondWith(method, url, body) {
2856
- if (arguments.length == 1 && typeof method != "function") {
2857
- this.response = responseArray(method);
2858
- return;
2859
- }
2860
-
2861
- if (!this.responses) { this.responses = []; }
2862
-
2863
- if (arguments.length == 1) {
2864
- body = method;
2865
- url = method = null;
2866
- }
2867
-
2868
- if (arguments.length == 2) {
2869
- body = url;
2870
- url = method;
2871
- method = null;
2872
- }
2873
-
2874
- push.call(this.responses, {
2875
- method: method,
2876
- url: url,
2877
- response: typeof body == "function" ? body : responseArray(body)
2878
- });
2879
- },
2880
-
2881
- respond: function respond() {
2882
- if (arguments.length > 0) this.respondWith.apply(this, arguments);
2883
- var queue = this.queue || [];
2884
- var request;
2885
-
2886
- while(request = queue.shift()) {
2887
- this.processRequest(request);
2888
- }
2889
- },
2890
-
2891
- processRequest: function processRequest(request) {
2892
- try {
2893
- if (request.aborted) {
2894
- return;
2895
- }
2896
-
2897
- var response = this.response || [404, {}, ""];
2898
-
2899
- if (this.responses) {
2900
- for (var i = 0, l = this.responses.length; i < l; i++) {
2901
- if (match.call(this, this.responses[i], request)) {
2902
- response = this.responses[i].response;
2903
- break;
2904
- }
2905
- }
2906
- }
2907
-
2908
- if (request.readyState != 4) {
2909
- request.respond(response[0], response[1], response[2]);
2910
- }
2911
- } catch (e) {
2912
- sinon.logError("Fake server request processing", e);
2913
- }
2914
- },
2915
-
2916
- restore: function restore() {
2917
- return this.xhr.restore && this.xhr.restore.apply(this.xhr, arguments);
2918
- }
2919
- };
2920
- }());
2921
-
2922
- if (typeof module == "object" && typeof require == "function") {
2923
- module.exports = sinon;
2924
- }
2925
-
2926
- /**
2927
- * @depend fake_server.js
2928
- * @depend fake_timers.js
2929
- */
2930
- /*jslint browser: true, eqeqeq: false, onevar: false*/
2931
- /*global sinon*/
2932
- /**
2933
- * Add-on for sinon.fakeServer that automatically handles a fake timer along with
2934
- * the FakeXMLHttpRequest. The direct inspiration for this add-on is jQuery
2935
- * 1.3.x, which does not use xhr object's onreadystatehandler at all - instead,
2936
- * it polls the object for completion with setInterval. Dispite the direct
2937
- * motivation, there is nothing jQuery-specific in this file, so it can be used
2938
- * in any environment where the ajax implementation depends on setInterval or
2939
- * setTimeout.
2940
- *
2941
- * @author Christian Johansen (christian@cjohansen.no)
2942
- * @license BSD
2943
- *
2944
- * Copyright (c) 2010-2011 Christian Johansen
2945
- */
2946
-
2947
- (function () {
2948
- function Server() {}
2949
- Server.prototype = sinon.fakeServer;
2950
-
2951
- sinon.fakeServerWithClock = new Server();
2952
-
2953
- sinon.fakeServerWithClock.addRequest = function addRequest(xhr) {
2954
- if (xhr.async) {
2955
- if (typeof setTimeout.clock == "object") {
2956
- this.clock = setTimeout.clock;
2957
- } else {
2958
- this.clock = sinon.useFakeTimers();
2959
- this.resetClock = true;
2960
- }
2961
-
2962
- if (!this.longestTimeout) {
2963
- var clockSetTimeout = this.clock.setTimeout;
2964
- var clockSetInterval = this.clock.setInterval;
2965
- var server = this;
2966
-
2967
- this.clock.setTimeout = function (fn, timeout) {
2968
- server.longestTimeout = Math.max(timeout, server.longestTimeout || 0);
2969
-
2970
- return clockSetTimeout.apply(this, arguments);
2971
- };
2972
-
2973
- this.clock.setInterval = function (fn, timeout) {
2974
- server.longestTimeout = Math.max(timeout, server.longestTimeout || 0);
2975
-
2976
- return clockSetInterval.apply(this, arguments);
2977
- };
2978
- }
2979
- }
2980
-
2981
- return sinon.fakeServer.addRequest.call(this, xhr);
2982
- };
2983
-
2984
- sinon.fakeServerWithClock.respond = function respond() {
2985
- var returnVal = sinon.fakeServer.respond.apply(this, arguments);
2986
-
2987
- if (this.clock) {
2988
- this.clock.tick(this.longestTimeout || 0);
2989
- this.longestTimeout = 0;
2990
-
2991
- if (this.resetClock) {
2992
- this.clock.restore();
2993
- this.resetClock = false;
2994
- }
2995
- }
2996
-
2997
- return returnVal;
2998
- };
2999
-
3000
- sinon.fakeServerWithClock.restore = function restore() {
3001
- if (this.clock) {
3002
- this.clock.restore();
3003
- }
3004
-
3005
- return sinon.fakeServer.restore.apply(this, arguments);
3006
- };
3007
- }());
3008
-
3009
- /**
3010
- * @depend ../sinon.js
3011
- * @depend collection.js
3012
- * @depend util/fake_timers.js
3013
- * @depend util/fake_server_with_clock.js
3014
- */
3015
- /*jslint eqeqeq: false, onevar: false, plusplus: false*/
3016
- /*global require, module*/
3017
- /**
3018
- * Manages fake collections as well as fake utilities such as Sinon's
3019
- * timers and fake XHR implementation in one convenient object.
3020
- *
3021
- * @author Christian Johansen (christian@cjohansen.no)
3022
- * @license BSD
3023
- *
3024
- * Copyright (c) 2010-2011 Christian Johansen
3025
- */
3026
-
3027
- if (typeof module == "object" && typeof require == "function") {
3028
- var sinon = require("../sinon");
3029
- sinon.extend(sinon, require("./util/fake_timers"));
3030
- }
3031
-
3032
- (function () {
3033
- var push = [].push;
3034
-
3035
- function exposeValue(sandbox, config, key, value) {
3036
- if (!value) {
3037
- return;
3038
- }
3039
-
3040
- if (config.injectInto) {
3041
- config.injectInto[key] = value;
3042
- } else {
3043
- push.call(sandbox.args, value);
3044
- }
3045
- }
3046
-
3047
- function prepareSandboxFromConfig(config) {
3048
- var sandbox = sinon.create(sinon.sandbox);
3049
-
3050
- if (config.useFakeServer) {
3051
- if (typeof config.useFakeServer == "object") {
3052
- sandbox.serverPrototype = config.useFakeServer;
3053
- }
3054
-
3055
- sandbox.useFakeServer();
3056
- }
3057
-
3058
- if (config.useFakeTimers) {
3059
- if (typeof config.useFakeTimers == "object") {
3060
- sandbox.useFakeTimers.apply(sandbox, config.useFakeTimers);
3061
- } else {
3062
- sandbox.useFakeTimers();
3063
- }
3064
- }
3065
-
3066
- return sandbox;
3067
- }
3068
-
3069
- sinon.sandbox = sinon.extend(sinon.create(sinon.collection), {
3070
- useFakeTimers: function useFakeTimers() {
3071
- this.clock = sinon.useFakeTimers.apply(sinon, arguments);
3072
-
3073
- return this.add(this.clock);
3074
- },
3075
-
3076
- serverPrototype: sinon.fakeServer,
3077
-
3078
- useFakeServer: function useFakeServer() {
3079
- var proto = this.serverPrototype || sinon.fakeServer;
3080
-
3081
- if (!proto || !proto.create) {
3082
- return null;
3083
- }
3084
-
3085
- this.server = proto.create();
3086
- return this.add(this.server);
3087
- },
3088
-
3089
- inject: function (obj) {
3090
- sinon.collection.inject.call(this, obj);
3091
-
3092
- if (this.clock) {
3093
- obj.clock = this.clock;
3094
- }
3095
-
3096
- if (this.server) {
3097
- obj.server = this.server;
3098
- obj.requests = this.server.requests;
3099
- }
3100
-
3101
- return obj;
3102
- },
3103
-
3104
- create: function (config) {
3105
- if (!config) {
3106
- return sinon.create(sinon.sandbox);
3107
- }
3108
-
3109
- var sandbox = prepareSandboxFromConfig(config);
3110
- sandbox.args = sandbox.args || [];
3111
- var prop, value, exposed = sandbox.inject({});
3112
-
3113
- if (config.properties) {
3114
- for (var i = 0, l = config.properties.length; i < l; i++) {
3115
- prop = config.properties[i];
3116
- value = exposed[prop] || prop == "sandbox" && sandbox;
3117
- exposeValue(sandbox, config, prop, value);
3118
- }
3119
- } else {
3120
- exposeValue(sandbox, config, "sandbox", value);
3121
- }
3122
-
3123
- return sandbox;
3124
- }
3125
- });
3126
-
3127
- sinon.sandbox.useFakeXMLHttpRequest = sinon.sandbox.useFakeServer;
3128
-
3129
- if (typeof module != "undefined") {
3130
- module.exports = sinon.sandbox;
3131
- }
3132
- }());
3133
-
3134
- /**
3135
- * @depend ../sinon.js
3136
- * @depend stub.js
3137
- * @depend mock.js
3138
- * @depend sandbox.js
3139
- */
3140
- /*jslint eqeqeq: false, onevar: false, forin: true, plusplus: false*/
3141
- /*global module, require, sinon*/
3142
- /**
3143
- * Test function, sandboxes fakes
3144
- *
3145
- * @author Christian Johansen (christian@cjohansen.no)
3146
- * @license BSD
3147
- *
3148
- * Copyright (c) 2010-2011 Christian Johansen
3149
- */
3150
-
3151
- (function (sinon) {
3152
- var commonJSModule = typeof module == "object" && typeof require == "function";
3153
-
3154
- if (!sinon && commonJSModule) {
3155
- sinon = require("../sinon");
3156
- }
3157
-
3158
- if (!sinon) {
3159
- return;
3160
- }
3161
-
3162
- function test(callback) {
3163
- var type = typeof callback;
3164
-
3165
- if (type != "function") {
3166
- throw new TypeError("sinon.test needs to wrap a test function, got " + type);
3167
- }
3168
-
3169
- return function () {
3170
- var config = sinon.getConfig(sinon.config);
3171
- config.injectInto = config.injectIntoThis && this || config.injectInto;
3172
- var sandbox = sinon.sandbox.create(config);
3173
- var exception, result;
3174
- var args = Array.prototype.slice.call(arguments).concat(sandbox.args);
3175
-
3176
- try {
3177
- result = callback.apply(this, args);
3178
- } finally {
3179
- sandbox.verifyAndRestore();
3180
- }
3181
-
3182
- return result;
3183
- };
3184
- }
3185
-
3186
- test.config = {
3187
- injectIntoThis: true,
3188
- injectInto: null,
3189
- properties: ["spy", "stub", "mock", "clock", "server", "requests"],
3190
- useFakeTimers: true,
3191
- useFakeServer: true
3192
- };
3193
-
3194
- if (commonJSModule) {
3195
- module.exports = test;
3196
- } else {
3197
- sinon.test = test;
3198
- }
3199
- }(typeof sinon == "object" && sinon || null));
3200
-
3201
- /**
3202
- * @depend ../sinon.js
3203
- * @depend test.js
3204
- */
3205
- /*jslint eqeqeq: false, onevar: false, eqeqeq: false*/
3206
- /*global module, require, sinon*/
3207
- /**
3208
- * Test case, sandboxes all test functions
3209
- *
3210
- * @author Christian Johansen (christian@cjohansen.no)
3211
- * @license BSD
3212
- *
3213
- * Copyright (c) 2010-2011 Christian Johansen
3214
- */
3215
-
3216
- (function (sinon) {
3217
- var commonJSModule = typeof module == "object" && typeof require == "function";
3218
-
3219
- if (!sinon && commonJSModule) {
3220
- sinon = require("../sinon");
3221
- }
3222
-
3223
- if (!sinon || !Object.prototype.hasOwnProperty) {
3224
- return;
3225
- }
3226
-
3227
- function createTest(property, setUp, tearDown) {
3228
- return function () {
3229
- if (setUp) {
3230
- setUp.apply(this, arguments);
3231
- }
3232
-
3233
- var exception, result;
3234
-
3235
- try {
3236
- result = property.apply(this, arguments);
3237
- } catch (e) {
3238
- exception = e;
3239
- }
3240
-
3241
- if (tearDown) {
3242
- tearDown.apply(this, arguments);
3243
- }
3244
-
3245
- if (exception) {
3246
- throw exception;
3247
- }
3248
-
3249
- return result;
3250
- };
3251
- }
3252
-
3253
- function testCase(tests, prefix) {
3254
- /*jsl:ignore*/
3255
- if (!tests || typeof tests != "object") {
3256
- throw new TypeError("sinon.testCase needs an object with test functions");
3257
- }
3258
- /*jsl:end*/
3259
-
3260
- prefix = prefix || "test";
3261
- var rPrefix = new RegExp("^" + prefix);
3262
- var methods = {}, testName, property, method;
3263
- var setUp = tests.setUp;
3264
- var tearDown = tests.tearDown;
3265
-
3266
- for (testName in tests) {
3267
- if (tests.hasOwnProperty(testName)) {
3268
- property = tests[testName];
3269
-
3270
- if (/^(setUp|tearDown)$/.test(testName)) {
3271
- continue;
3272
- }
3273
-
3274
- if (typeof property == "function" && rPrefix.test(testName)) {
3275
- method = property;
3276
-
3277
- if (setUp || tearDown) {
3278
- method = createTest(property, setUp, tearDown);
3279
- }
3280
-
3281
- methods[testName] = sinon.test(method);
3282
- } else {
3283
- methods[testName] = tests[testName];
3284
- }
3285
- }
3286
- }
3287
-
3288
- return methods;
3289
- }
3290
-
3291
- if (commonJSModule) {
3292
- module.exports = testCase;
3293
- } else {
3294
- sinon.testCase = testCase;
3295
- }
3296
- }(typeof sinon == "object" && sinon || null));
3297
-
3298
- /**
3299
- * @depend ../sinon.js
3300
- * @depend stub.js
3301
- */
3302
- /*jslint eqeqeq: false, onevar: false, nomen: false, plusplus: false*/
3303
- /*global module, require, sinon*/
3304
- /**
3305
- * Assertions matching the test spy retrieval interface.
3306
- *
3307
- * @author Christian Johansen (christian@cjohansen.no)
3308
- * @license BSD
3309
- *
3310
- * Copyright (c) 2010-2011 Christian Johansen
3311
- */
3312
-
3313
- (function (sinon, global) {
3314
- var commonJSModule = typeof module == "object" && typeof require == "function";
3315
- var slice = Array.prototype.slice;
3316
- var assert;
3317
-
3318
- if (!sinon && commonJSModule) {
3319
- sinon = require("../sinon");
3320
- }
3321
-
3322
- if (!sinon) {
3323
- return;
3324
- }
3325
-
3326
- function verifyIsStub() {
3327
- var method;
3328
-
3329
- for (var i = 0, l = arguments.length; i < l; ++i) {
3330
- method = arguments[i];
3331
-
3332
- if (!method) {
3333
- assert.fail("fake is not a spy");
3334
- }
3335
-
3336
- if (typeof method != "function") {
3337
- assert.fail(method + " is not a function");
3338
- }
3339
-
3340
- if (typeof method.getCall != "function") {
3341
- assert.fail(method + " is not stubbed");
3342
- }
3343
- }
3344
- }
3345
-
3346
- function failAssertion(object, msg) {
3347
- object = object || global;
3348
- var failMethod = object.fail || assert.fail;
3349
- failMethod.call(object, msg);
3350
- }
3351
-
3352
- function mirrorPropAsAssertion(name, method, message) {
3353
- if (arguments.length == 2) {
3354
- message = method;
3355
- method = name;
3356
- }
3357
-
3358
- assert[name] = function (fake) {
3359
- verifyIsStub(fake);
3360
-
3361
- var args = slice.call(arguments, 1);
3362
- var failed = false;
3363
-
3364
- if (typeof method == "function") {
3365
- failed = !method(fake);
3366
- } else {
3367
- failed = typeof fake[method] == "function" ?
3368
- !fake[method].apply(fake, args) : !fake[method];
3369
- }
3370
-
3371
- if (failed) {
3372
- failAssertion(this, fake.printf.apply(fake, [message].concat(args)));
3373
- } else {
3374
- assert.pass(name);
3375
- }
3376
- };
3377
- }
3378
-
3379
- function exposedName(prefix, prop) {
3380
- return !prefix || /^fail/.test(prop) ? prop :
3381
- prefix + prop.slice(0, 1).toUpperCase() + prop.slice(1);
3382
- };
3383
-
3384
- assert = {
3385
- failException: "AssertError",
3386
-
3387
- fail: function fail(message) {
3388
- var error = new Error(message);
3389
- error.name = this.failException || assert.failException;
3390
-
3391
- throw error;
3392
- },
3393
-
3394
- pass: function pass(assertion) {},
3395
-
3396
- callOrder: function assertCallOrder() {
3397
- verifyIsStub.apply(null, arguments);
3398
- var expected = "", actual = "";
3399
-
3400
- if (!sinon.calledInOrder(arguments)) {
3401
- try {
3402
- expected = [].join.call(arguments, ", ");
3403
- actual = sinon.orderByFirstCall(slice.call(arguments)).join(", ");
3404
- } catch (e) {
3405
- // If this fails, we'll just fall back to the blank string
3406
- }
3407
-
3408
- failAssertion(this, "expected " + expected + " to be " +
3409
- "called in order but were called as " + actual);
3410
- } else {
3411
- assert.pass("callOrder");
3412
- }
3413
- },
3414
-
3415
- callCount: function assertCallCount(method, count) {
3416
- verifyIsStub(method);
3417
-
3418
- if (method.callCount != count) {
3419
- var msg = "expected %n to be called " + sinon.timesInWords(count) +
3420
- " but was called %c%C";
3421
- failAssertion(this, method.printf(msg));
3422
- } else {
3423
- assert.pass("callCount");
3424
- }
3425
- },
3426
-
3427
- expose: function expose(target, options) {
3428
- if (!target) {
3429
- throw new TypeError("target is null or undefined");
3430
- }
3431
-
3432
- var o = options || {};
3433
- var prefix = typeof o.prefix == "undefined" && "assert" || o.prefix;
3434
- var includeFail = typeof o.includeFail == "undefined" || !!o.includeFail;
3435
-
3436
- for (var method in this) {
3437
- if (method != "export" && (includeFail || !/^(fail)/.test(method))) {
3438
- target[exposedName(prefix, method)] = this[method];
3439
- }
3440
- }
3441
-
3442
- return target;
3443
- }
3444
- };
3445
-
3446
- mirrorPropAsAssertion("called", "expected %n to have been called at least once but was never called");
3447
- mirrorPropAsAssertion("notCalled", function (spy) { return !spy.called; },
3448
- "expected %n to not have been called but was called %c%C");
3449
- mirrorPropAsAssertion("calledOnce", "expected %n to be called once but was called %c%C");
3450
- mirrorPropAsAssertion("calledTwice", "expected %n to be called twice but was called %c%C");
3451
- mirrorPropAsAssertion("calledThrice", "expected %n to be called thrice but was called %c%C");
3452
- mirrorPropAsAssertion("calledOn", "expected %n to be called with %1 as this but was called with %t");
3453
- mirrorPropAsAssertion("alwaysCalledOn", "expected %n to always be called with %1 as this but was called with %t");
3454
- mirrorPropAsAssertion("calledWith", "expected %n to be called with arguments %*%C");
3455
- mirrorPropAsAssertion("alwaysCalledWith", "expected %n to always be called with arguments %*%C");
3456
- mirrorPropAsAssertion("calledWithExactly", "expected %n to be called with exact arguments %*%C");
3457
- mirrorPropAsAssertion("alwaysCalledWithExactly", "expected %n to always be called with exact arguments %*%C");
3458
- mirrorPropAsAssertion("neverCalledWith", "expected %n to never be called with arguments %*%C");
3459
- mirrorPropAsAssertion("threw", "%n did not throw exception%C");
3460
- mirrorPropAsAssertion("alwaysThrew", "%n did not always throw exception%C");
3461
-
3462
- if (commonJSModule) {
3463
- module.exports = assert;
3464
- } else {
3465
- sinon.assert = assert;
3466
- }
3467
- }(typeof sinon == "object" && sinon || null, typeof window != "undefined" ? window : global));
3468
-
3469
- return sinon;}.call(typeof window != 'undefined' && window || {}));