oxymoron 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (854) hide show
  1. checksums.yaml +7 -0
  2. data/.DS_Store +0 -0
  3. data/.gitignore +10 -0
  4. data/Gemfile +13 -0
  5. data/MIT-LICENSE +20 -0
  6. data/README.RU.md +324 -0
  7. data/README.md +319 -0
  8. data/Rakefile +34 -0
  9. data/app/.DS_Store +0 -0
  10. data/app/assets/.DS_Store +0 -0
  11. data/app/assets/javascripts/.DS_Store +0 -0
  12. data/app/assets/javascripts/oxymoron/.DS_Store +0 -0
  13. data/app/assets/javascripts/oxymoron/config.js.erb +5 -0
  14. data/app/assets/javascripts/oxymoron/config/debug.js.erb +4 -0
  15. data/app/assets/javascripts/oxymoron/config/http.js +8 -0
  16. data/app/assets/javascripts/oxymoron/config/states.js.erb +89 -0
  17. data/app/assets/javascripts/oxymoron/directives.js.erb +6 -0
  18. data/app/assets/javascripts/oxymoron/directives/checklist_model.js +141 -0
  19. data/app/assets/javascripts/oxymoron/directives/click_outside.js +25 -0
  20. data/app/assets/javascripts/oxymoron/directives/content_for.js +24 -0
  21. data/app/assets/javascripts/oxymoron/directives/fileupload.js +68 -0
  22. data/app/assets/javascripts/oxymoron/notifier.js.erb +39 -0
  23. data/app/assets/javascripts/oxymoron/oxymoron.js.erb +11 -0
  24. data/app/assets/javascripts/oxymoron/routes.js.erb +66 -0
  25. data/app/assets/javascripts/oxymoron/services.js.erb +6 -0
  26. data/app/assets/javascripts/oxymoron/services/interceptor.js +20 -0
  27. data/app/assets/javascripts/oxymoron/services/resources.js.erb +12 -0
  28. data/app/assets/javascripts/oxymoron/services/sign.js +25 -0
  29. data/app/assets/javascripts/oxymoron/services/validate.js +41 -0
  30. data/app/assets/javascripts/oxymoron/states.js.erb +3 -0
  31. data/app/helpers/form_helper.rb +35 -0
  32. data/app/helpers/oxymoron_form_builder.rb +81 -0
  33. data/lib/.DS_Store +0 -0
  34. data/lib/oxymoron.rb +123 -0
  35. data/lib/oxymoron/concern.rb +21 -0
  36. data/lib/oxymoron/engine.rb +35 -0
  37. data/lib/oxymoron/version.rb +3 -0
  38. data/lib/tasks/oxymoron_tasks.rake +4 -0
  39. data/oxymoron.gemspec +24 -0
  40. data/test/dummy/README.rdoc +28 -0
  41. data/test/dummy/Rakefile +6 -0
  42. data/test/dummy/app/assets/images/.keep +0 -0
  43. data/test/dummy/app/assets/javascripts/application.js +13 -0
  44. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  45. data/test/dummy/app/controllers/application_controller.rb +5 -0
  46. data/test/dummy/app/controllers/concerns/.keep +0 -0
  47. data/test/dummy/app/helpers/application_helper.rb +2 -0
  48. data/test/dummy/app/mailers/.keep +0 -0
  49. data/test/dummy/app/models/.keep +0 -0
  50. data/test/dummy/app/models/concerns/.keep +0 -0
  51. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  52. data/test/dummy/config.ru +4 -0
  53. data/test/dummy/config/application.rb +26 -0
  54. data/test/dummy/config/boot.rb +5 -0
  55. data/test/dummy/config/database.yml +25 -0
  56. data/test/dummy/config/environment.rb +5 -0
  57. data/test/dummy/config/environments/development.rb +41 -0
  58. data/test/dummy/config/environments/production.rb +79 -0
  59. data/test/dummy/config/environments/test.rb +42 -0
  60. data/test/dummy/config/initializers/assets.rb +11 -0
  61. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  62. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  63. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  64. data/test/dummy/config/initializers/inflections.rb +16 -0
  65. data/test/dummy/config/initializers/mime_types.rb +4 -0
  66. data/test/dummy/config/initializers/session_store.rb +3 -0
  67. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  68. data/test/dummy/config/locales/en.yml +23 -0
  69. data/test/dummy/config/routes.rb +56 -0
  70. data/test/dummy/config/secrets.yml +22 -0
  71. data/test/dummy/lib/assets/.keep +0 -0
  72. data/test/dummy/log/.keep +0 -0
  73. data/test/dummy/public/404.html +67 -0
  74. data/test/dummy/public/422.html +67 -0
  75. data/test/dummy/public/500.html +66 -0
  76. data/test/dummy/public/favicon.ico +0 -0
  77. data/test/oxymoron_test.rb +7 -0
  78. data/test/test_helper.rb +19 -0
  79. data/vendor/.DS_Store +0 -0
  80. data/vendor/assets/.DS_Store +0 -0
  81. data/vendor/assets/javascripts/.DS_Store +0 -0
  82. data/vendor/assets/javascripts/oxymoron/.DS_Store +0 -0
  83. data/vendor/assets/javascripts/oxymoron/angular-animate.js +3928 -0
  84. data/vendor/assets/javascripts/oxymoron/angular-aria.js +397 -0
  85. data/vendor/assets/javascripts/oxymoron/angular-cookies.js +321 -0
  86. data/vendor/assets/javascripts/oxymoron/angular-loader.js +443 -0
  87. data/vendor/assets/javascripts/oxymoron/angular-message-format.js +980 -0
  88. data/vendor/assets/javascripts/oxymoron/angular-messages.js +685 -0
  89. data/vendor/assets/javascripts/oxymoron/angular-mocks.js +2470 -0
  90. data/vendor/assets/javascripts/oxymoron/angular-resource.js +675 -0
  91. data/vendor/assets/javascripts/oxymoron/angular-route.js +991 -0
  92. data/vendor/assets/javascripts/oxymoron/angular-sanitize.js +683 -0
  93. data/vendor/assets/javascripts/oxymoron/angular-scenario.js +40324 -0
  94. data/vendor/assets/javascripts/oxymoron/angular-touch.js +628 -0
  95. data/vendor/assets/javascripts/oxymoron/angular-ui-router.js +4390 -0
  96. data/vendor/assets/javascripts/oxymoron/angular.js +28904 -0
  97. data/vendor/assets/javascripts/oxymoron/dcbox.js +311 -0
  98. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_aa-dj.js +128 -0
  99. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_aa-er.js +128 -0
  100. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_aa-et.js +128 -0
  101. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_aa.js +128 -0
  102. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_af-na.js +110 -0
  103. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_af-za.js +110 -0
  104. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_af.js +110 -0
  105. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_agq-cm.js +128 -0
  106. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_agq.js +128 -0
  107. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ak-gh.js +128 -0
  108. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ak.js +128 -0
  109. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_am-et.js +110 -0
  110. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_am.js +110 -0
  111. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ar-001.js +110 -0
  112. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ar-ae.js +110 -0
  113. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ar-bh.js +110 -0
  114. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ar-dj.js +110 -0
  115. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ar-dz.js +110 -0
  116. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ar-eg.js +110 -0
  117. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ar-eh.js +110 -0
  118. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ar-er.js +110 -0
  119. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ar-il.js +110 -0
  120. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ar-iq.js +110 -0
  121. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ar-jo.js +110 -0
  122. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ar-km.js +110 -0
  123. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ar-kw.js +110 -0
  124. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ar-lb.js +110 -0
  125. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ar-ly.js +110 -0
  126. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ar-ma.js +110 -0
  127. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ar-mr.js +110 -0
  128. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ar-om.js +110 -0
  129. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ar-ps.js +110 -0
  130. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ar-qa.js +110 -0
  131. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ar-sa.js +110 -0
  132. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ar-sd.js +110 -0
  133. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ar-so.js +110 -0
  134. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ar-ss.js +110 -0
  135. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ar-sy.js +110 -0
  136. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ar-td.js +110 -0
  137. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ar-tn.js +110 -0
  138. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ar-ye.js +110 -0
  139. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ar.js +110 -0
  140. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_as-in.js +128 -0
  141. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_as.js +128 -0
  142. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_asa-tz.js +128 -0
  143. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_asa.js +128 -0
  144. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ast-es.js +128 -0
  145. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ast.js +128 -0
  146. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_az-cyrl-az.js +110 -0
  147. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_az-cyrl.js +110 -0
  148. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_az-latn-az.js +110 -0
  149. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_az-latn.js +110 -0
  150. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_az.js +110 -0
  151. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_bas-cm.js +128 -0
  152. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_bas.js +128 -0
  153. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_be-by.js +110 -0
  154. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_be.js +110 -0
  155. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_bem-zm.js +128 -0
  156. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_bem.js +128 -0
  157. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_bez-tz.js +128 -0
  158. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_bez.js +128 -0
  159. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_bg-bg.js +110 -0
  160. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_bg.js +110 -0
  161. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_bm-latn-ml.js +128 -0
  162. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_bm-latn.js +128 -0
  163. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_bm-ml.js +115 -0
  164. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_bm.js +128 -0
  165. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_bn-bd.js +110 -0
  166. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_bn-in.js +110 -0
  167. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_bn.js +110 -0
  168. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_bo-cn.js +128 -0
  169. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_bo-in.js +128 -0
  170. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_bo.js +128 -0
  171. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_br-fr.js +110 -0
  172. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_br.js +110 -0
  173. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_brx-in.js +128 -0
  174. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_brx.js +128 -0
  175. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_bs-cyrl-ba.js +128 -0
  176. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_bs-cyrl.js +128 -0
  177. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_bs-latn-ba.js +128 -0
  178. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_bs-latn.js +128 -0
  179. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_bs.js +128 -0
  180. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_byn-er.js +115 -0
  181. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_byn.js +115 -0
  182. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ca-ad.js +128 -0
  183. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ca-es-valencia.js +128 -0
  184. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ca-es.js +128 -0
  185. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ca-fr.js +128 -0
  186. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ca-it.js +128 -0
  187. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ca.js +128 -0
  188. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_cgg-ug.js +128 -0
  189. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_cgg.js +128 -0
  190. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_chr-us.js +110 -0
  191. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_chr.js +110 -0
  192. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ckb-arab-iq.js +128 -0
  193. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ckb-arab-ir.js +128 -0
  194. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ckb-arab.js +128 -0
  195. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ckb-iq.js +128 -0
  196. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ckb-ir.js +128 -0
  197. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ckb-latn-iq.js +128 -0
  198. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ckb-latn.js +128 -0
  199. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ckb.js +128 -0
  200. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_cs-cz.js +128 -0
  201. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_cs.js +128 -0
  202. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_cy-gb.js +110 -0
  203. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_cy.js +110 -0
  204. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_da-dk.js +141 -0
  205. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_da-gl.js +141 -0
  206. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_da.js +141 -0
  207. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_dav-ke.js +128 -0
  208. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_dav.js +128 -0
  209. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_de-at.js +128 -0
  210. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_de-be.js +128 -0
  211. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_de-ch.js +128 -0
  212. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_de-de.js +128 -0
  213. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_de-li.js +128 -0
  214. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_de-lu.js +128 -0
  215. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_de.js +128 -0
  216. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_dje-ne.js +128 -0
  217. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_dje.js +128 -0
  218. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_dsb-de.js +128 -0
  219. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_dsb.js +128 -0
  220. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_dua-cm.js +128 -0
  221. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_dua.js +128 -0
  222. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_dyo-sn.js +128 -0
  223. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_dyo.js +128 -0
  224. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_dz-bt.js +128 -0
  225. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_dz.js +128 -0
  226. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ebu-ke.js +128 -0
  227. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ebu.js +128 -0
  228. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ee-gh.js +128 -0
  229. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ee-tg.js +128 -0
  230. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ee.js +128 -0
  231. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_el-cy.js +110 -0
  232. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_el-gr.js +110 -0
  233. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_el.js +110 -0
  234. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-001.js +128 -0
  235. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-150.js +128 -0
  236. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-ag.js +128 -0
  237. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-ai.js +128 -0
  238. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-as.js +128 -0
  239. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-au.js +128 -0
  240. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-bb.js +128 -0
  241. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-be.js +128 -0
  242. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-bm.js +128 -0
  243. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-bs.js +128 -0
  244. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-bw.js +128 -0
  245. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-bz.js +128 -0
  246. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-ca.js +128 -0
  247. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-cc.js +128 -0
  248. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-ck.js +128 -0
  249. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-cm.js +128 -0
  250. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-cx.js +128 -0
  251. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-dg.js +128 -0
  252. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-dm.js +128 -0
  253. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-er.js +128 -0
  254. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-fj.js +128 -0
  255. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-fk.js +128 -0
  256. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-fm.js +128 -0
  257. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-gb.js +128 -0
  258. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-gd.js +128 -0
  259. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-gg.js +128 -0
  260. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-gh.js +128 -0
  261. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-gi.js +128 -0
  262. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-gm.js +128 -0
  263. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-gu.js +128 -0
  264. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-gy.js +128 -0
  265. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-hk.js +128 -0
  266. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-ie.js +128 -0
  267. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-im.js +128 -0
  268. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-in.js +128 -0
  269. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-io.js +128 -0
  270. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-iso.js +128 -0
  271. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-je.js +128 -0
  272. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-jm.js +128 -0
  273. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-ke.js +128 -0
  274. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-ki.js +128 -0
  275. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-kn.js +128 -0
  276. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-ky.js +128 -0
  277. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-lc.js +128 -0
  278. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-lr.js +128 -0
  279. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-ls.js +128 -0
  280. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-mg.js +128 -0
  281. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-mh.js +128 -0
  282. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-mo.js +128 -0
  283. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-mp.js +128 -0
  284. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-ms.js +128 -0
  285. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-mt.js +128 -0
  286. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-mu.js +128 -0
  287. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-mw.js +128 -0
  288. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-my.js +128 -0
  289. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-na.js +128 -0
  290. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-nf.js +128 -0
  291. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-ng.js +128 -0
  292. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-nr.js +128 -0
  293. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-nu.js +128 -0
  294. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-nz.js +128 -0
  295. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-pg.js +128 -0
  296. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-ph.js +128 -0
  297. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-pk.js +128 -0
  298. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-pn.js +128 -0
  299. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-pr.js +128 -0
  300. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-pw.js +128 -0
  301. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-rw.js +128 -0
  302. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-sb.js +128 -0
  303. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-sc.js +128 -0
  304. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-sd.js +128 -0
  305. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-sg.js +128 -0
  306. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-sh.js +128 -0
  307. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-sl.js +128 -0
  308. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-ss.js +128 -0
  309. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-sx.js +128 -0
  310. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-sz.js +128 -0
  311. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-tc.js +128 -0
  312. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-tk.js +128 -0
  313. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-to.js +128 -0
  314. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-tt.js +128 -0
  315. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-tv.js +128 -0
  316. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-tz.js +128 -0
  317. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-ug.js +128 -0
  318. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-um.js +128 -0
  319. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-us.js +128 -0
  320. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-vc.js +128 -0
  321. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-vg.js +128 -0
  322. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-vi.js +128 -0
  323. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-vu.js +128 -0
  324. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-ws.js +128 -0
  325. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-za.js +128 -0
  326. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-zm.js +128 -0
  327. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en-zw.js +128 -0
  328. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_en.js +128 -0
  329. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_eo-001.js +128 -0
  330. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_eo.js +128 -0
  331. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_es-419.js +110 -0
  332. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_es-ar.js +110 -0
  333. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_es-bo.js +110 -0
  334. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_es-cl.js +110 -0
  335. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_es-co.js +110 -0
  336. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_es-cr.js +110 -0
  337. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_es-cu.js +110 -0
  338. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_es-do.js +110 -0
  339. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_es-ea.js +110 -0
  340. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_es-ec.js +110 -0
  341. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_es-es.js +110 -0
  342. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_es-gq.js +110 -0
  343. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_es-gt.js +110 -0
  344. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_es-hn.js +110 -0
  345. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_es-ic.js +110 -0
  346. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_es-mx.js +110 -0
  347. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_es-ni.js +110 -0
  348. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_es-pa.js +110 -0
  349. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_es-pe.js +110 -0
  350. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_es-ph.js +110 -0
  351. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_es-pr.js +110 -0
  352. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_es-py.js +110 -0
  353. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_es-sv.js +110 -0
  354. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_es-us.js +110 -0
  355. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_es-uy.js +110 -0
  356. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_es-ve.js +110 -0
  357. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_es.js +110 -0
  358. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_et-ee.js +128 -0
  359. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_et.js +128 -0
  360. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_eu-es.js +110 -0
  361. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_eu.js +110 -0
  362. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ewo-cm.js +128 -0
  363. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ewo.js +128 -0
  364. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fa-af.js +110 -0
  365. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fa-ir.js +110 -0
  366. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fa.js +110 -0
  367. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ff-cm.js +128 -0
  368. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ff-gn.js +128 -0
  369. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ff-mr.js +128 -0
  370. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ff-sn.js +128 -0
  371. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ff.js +128 -0
  372. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fi-fi.js +128 -0
  373. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fi.js +128 -0
  374. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fil-ph.js +128 -0
  375. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fil.js +128 -0
  376. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fo-fo.js +128 -0
  377. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fo.js +128 -0
  378. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-be.js +110 -0
  379. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-bf.js +110 -0
  380. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-bi.js +110 -0
  381. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-bj.js +110 -0
  382. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-bl.js +110 -0
  383. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-ca.js +110 -0
  384. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-cd.js +110 -0
  385. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-cf.js +110 -0
  386. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-cg.js +110 -0
  387. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-ch.js +110 -0
  388. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-ci.js +110 -0
  389. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-cm.js +110 -0
  390. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-dj.js +110 -0
  391. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-dz.js +110 -0
  392. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-fr.js +110 -0
  393. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-ga.js +110 -0
  394. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-gf.js +110 -0
  395. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-gn.js +110 -0
  396. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-gp.js +110 -0
  397. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-gq.js +110 -0
  398. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-ht.js +110 -0
  399. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-km.js +110 -0
  400. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-lu.js +110 -0
  401. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-ma.js +110 -0
  402. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-mc.js +110 -0
  403. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-mf.js +110 -0
  404. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-mg.js +110 -0
  405. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-ml.js +110 -0
  406. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-mq.js +110 -0
  407. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-mr.js +110 -0
  408. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-mu.js +110 -0
  409. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-nc.js +110 -0
  410. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-ne.js +110 -0
  411. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-pf.js +110 -0
  412. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-pm.js +110 -0
  413. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-re.js +110 -0
  414. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-rw.js +110 -0
  415. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-sc.js +110 -0
  416. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-sn.js +110 -0
  417. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-sy.js +110 -0
  418. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-td.js +110 -0
  419. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-tg.js +110 -0
  420. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-tn.js +110 -0
  421. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-vu.js +110 -0
  422. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-wf.js +110 -0
  423. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr-yt.js +110 -0
  424. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fr.js +110 -0
  425. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fur-it.js +128 -0
  426. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fur.js +128 -0
  427. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fy-nl.js +128 -0
  428. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_fy.js +128 -0
  429. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ga-ie.js +110 -0
  430. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ga.js +110 -0
  431. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_gd-gb.js +128 -0
  432. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_gd.js +128 -0
  433. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_gl-es.js +128 -0
  434. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_gl.js +128 -0
  435. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_gsw-ch.js +110 -0
  436. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_gsw-fr.js +110 -0
  437. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_gsw-li.js +110 -0
  438. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_gsw.js +110 -0
  439. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_gu-in.js +110 -0
  440. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_gu.js +110 -0
  441. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_guz-ke.js +128 -0
  442. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_guz.js +128 -0
  443. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_gv-im.js +128 -0
  444. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_gv.js +128 -0
  445. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ha-latn-gh.js +128 -0
  446. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ha-latn-ne.js +128 -0
  447. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ha-latn-ng.js +128 -0
  448. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ha-latn.js +128 -0
  449. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ha.js +128 -0
  450. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_haw-us.js +110 -0
  451. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_haw.js +110 -0
  452. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_he-il.js +128 -0
  453. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_he.js +128 -0
  454. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_hi-in.js +110 -0
  455. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_hi.js +110 -0
  456. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_hr-ba.js +128 -0
  457. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_hr-hr.js +128 -0
  458. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_hr.js +128 -0
  459. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_hsb-de.js +128 -0
  460. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_hsb.js +128 -0
  461. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_hu-hu.js +110 -0
  462. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_hu.js +110 -0
  463. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_hy-am.js +110 -0
  464. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_hy.js +110 -0
  465. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ia-fr.js +128 -0
  466. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ia.js +128 -0
  467. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_id-id.js +110 -0
  468. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_id.js +110 -0
  469. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ig-ng.js +128 -0
  470. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ig.js +128 -0
  471. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ii-cn.js +128 -0
  472. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ii.js +128 -0
  473. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_in.js +110 -0
  474. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_is-is.js +141 -0
  475. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_is.js +141 -0
  476. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_it-ch.js +128 -0
  477. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_it-it.js +128 -0
  478. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_it-sm.js +128 -0
  479. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_it.js +128 -0
  480. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_iw.js +128 -0
  481. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ja-jp.js +110 -0
  482. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ja.js +110 -0
  483. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_jgo-cm.js +128 -0
  484. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_jgo.js +128 -0
  485. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_jmc-tz.js +128 -0
  486. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_jmc.js +128 -0
  487. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ka-ge.js +110 -0
  488. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ka.js +110 -0
  489. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_kab-dz.js +128 -0
  490. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_kab.js +128 -0
  491. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_kam-ke.js +128 -0
  492. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_kam.js +128 -0
  493. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_kde-tz.js +128 -0
  494. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_kde.js +128 -0
  495. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_kea-cv.js +128 -0
  496. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_kea.js +128 -0
  497. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_khq-ml.js +128 -0
  498. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_khq.js +128 -0
  499. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ki-ke.js +128 -0
  500. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ki.js +128 -0
  501. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_kk-cyrl-kz.js +110 -0
  502. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_kk-cyrl.js +110 -0
  503. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_kk.js +110 -0
  504. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_kkj-cm.js +128 -0
  505. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_kkj.js +128 -0
  506. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_kl-gl.js +128 -0
  507. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_kl.js +128 -0
  508. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_kln-ke.js +128 -0
  509. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_kln.js +128 -0
  510. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_km-kh.js +110 -0
  511. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_km.js +110 -0
  512. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_kn-in.js +110 -0
  513. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_kn.js +110 -0
  514. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ko-kp.js +110 -0
  515. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ko-kr.js +110 -0
  516. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ko.js +110 -0
  517. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_kok-in.js +128 -0
  518. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_kok.js +128 -0
  519. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ks-arab-in.js +128 -0
  520. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ks-arab.js +128 -0
  521. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ks.js +128 -0
  522. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ksb-tz.js +128 -0
  523. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ksb.js +128 -0
  524. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ksf-cm.js +128 -0
  525. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ksf.js +128 -0
  526. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ksh-de.js +128 -0
  527. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ksh.js +128 -0
  528. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_kw-gb.js +128 -0
  529. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_kw.js +128 -0
  530. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ky-cyrl-kg.js +110 -0
  531. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ky-cyrl.js +110 -0
  532. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ky.js +110 -0
  533. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_lag-tz.js +128 -0
  534. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_lag.js +128 -0
  535. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_lb-lu.js +128 -0
  536. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_lb.js +128 -0
  537. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_lg-ug.js +128 -0
  538. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_lg.js +128 -0
  539. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_lkt-us.js +128 -0
  540. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_lkt.js +128 -0
  541. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ln-ao.js +110 -0
  542. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ln-cd.js +110 -0
  543. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ln-cf.js +110 -0
  544. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ln-cg.js +110 -0
  545. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ln.js +110 -0
  546. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_lo-la.js +110 -0
  547. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_lo.js +110 -0
  548. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_lt-lt.js +128 -0
  549. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_lt.js +128 -0
  550. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_lu-cd.js +128 -0
  551. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_lu.js +128 -0
  552. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_luo-ke.js +128 -0
  553. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_luo.js +128 -0
  554. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_luy-ke.js +128 -0
  555. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_luy.js +128 -0
  556. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_lv-lv.js +128 -0
  557. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_lv.js +128 -0
  558. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_mas-ke.js +128 -0
  559. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_mas-tz.js +128 -0
  560. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_mas.js +128 -0
  561. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_mer-ke.js +128 -0
  562. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_mer.js +128 -0
  563. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_mfe-mu.js +128 -0
  564. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_mfe.js +128 -0
  565. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_mg-mg.js +128 -0
  566. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_mg.js +128 -0
  567. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_mgh-mz.js +128 -0
  568. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_mgh.js +128 -0
  569. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_mgo-cm.js +128 -0
  570. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_mgo.js +128 -0
  571. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_mk-mk.js +128 -0
  572. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_mk.js +128 -0
  573. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ml-in.js +110 -0
  574. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ml.js +110 -0
  575. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_mn-cyrl-mn.js +110 -0
  576. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_mn-cyrl.js +110 -0
  577. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_mn.js +110 -0
  578. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_mr-in.js +110 -0
  579. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_mr.js +110 -0
  580. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ms-latn-bn.js +110 -0
  581. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ms-latn-my.js +110 -0
  582. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ms-latn-sg.js +110 -0
  583. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ms-latn.js +110 -0
  584. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ms.js +110 -0
  585. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_mt-mt.js +110 -0
  586. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_mt.js +110 -0
  587. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_mua-cm.js +128 -0
  588. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_mua.js +128 -0
  589. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_my-mm.js +110 -0
  590. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_my.js +110 -0
  591. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_naq-na.js +128 -0
  592. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_naq.js +128 -0
  593. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_nb-no.js +110 -0
  594. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_nb-sj.js +110 -0
  595. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_nb.js +110 -0
  596. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_nd-zw.js +128 -0
  597. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_nd.js +128 -0
  598. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ne-in.js +110 -0
  599. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ne-np.js +110 -0
  600. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ne.js +110 -0
  601. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_nl-aw.js +128 -0
  602. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_nl-be.js +128 -0
  603. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_nl-bq.js +128 -0
  604. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_nl-cw.js +128 -0
  605. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_nl-nl.js +128 -0
  606. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_nl-sr.js +128 -0
  607. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_nl-sx.js +128 -0
  608. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_nl.js +128 -0
  609. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_nmg-cm.js +128 -0
  610. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_nmg.js +128 -0
  611. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_nn-no.js +128 -0
  612. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_nn.js +128 -0
  613. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_nnh-cm.js +128 -0
  614. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_nnh.js +128 -0
  615. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_no-no.js +110 -0
  616. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_no.js +110 -0
  617. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_nr-za.js +128 -0
  618. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_nr.js +128 -0
  619. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_nso-za.js +128 -0
  620. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_nso.js +128 -0
  621. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_nus-sd.js +128 -0
  622. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_nus.js +128 -0
  623. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_nyn-ug.js +128 -0
  624. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_nyn.js +128 -0
  625. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_om-et.js +128 -0
  626. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_om-ke.js +128 -0
  627. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_om.js +128 -0
  628. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_or-in.js +110 -0
  629. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_or.js +110 -0
  630. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_os-ge.js +128 -0
  631. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_os-ru.js +128 -0
  632. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_os.js +128 -0
  633. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_pa-arab-pk.js +110 -0
  634. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_pa-arab.js +110 -0
  635. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_pa-guru-in.js +110 -0
  636. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_pa-guru.js +110 -0
  637. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_pa.js +110 -0
  638. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_pl-pl.js +128 -0
  639. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_pl.js +128 -0
  640. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ps-af.js +128 -0
  641. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ps.js +128 -0
  642. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_pt-ao.js +110 -0
  643. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_pt-br.js +110 -0
  644. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_pt-cv.js +110 -0
  645. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_pt-gw.js +110 -0
  646. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_pt-mo.js +110 -0
  647. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_pt-mz.js +110 -0
  648. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_pt-pt.js +110 -0
  649. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_pt-st.js +110 -0
  650. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_pt-tl.js +110 -0
  651. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_pt.js +110 -0
  652. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_qu-bo.js +128 -0
  653. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_qu-ec.js +128 -0
  654. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_qu-pe.js +128 -0
  655. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_qu.js +128 -0
  656. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_rm-ch.js +128 -0
  657. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_rm.js +128 -0
  658. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_rn-bi.js +128 -0
  659. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_rn.js +128 -0
  660. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ro-md.js +128 -0
  661. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ro-ro.js +128 -0
  662. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ro.js +128 -0
  663. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_rof-tz.js +128 -0
  664. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_rof.js +128 -0
  665. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ru-by.js +128 -0
  666. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ru-kg.js +128 -0
  667. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ru-kz.js +128 -0
  668. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ru-md.js +128 -0
  669. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ru-ru.js +128 -0
  670. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ru-ua.js +128 -0
  671. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ru.js +128 -0
  672. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_rw-rw.js +128 -0
  673. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_rw.js +128 -0
  674. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_rwk-tz.js +128 -0
  675. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_rwk.js +128 -0
  676. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sah-ru.js +128 -0
  677. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sah.js +128 -0
  678. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_saq-ke.js +128 -0
  679. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_saq.js +128 -0
  680. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sbp-tz.js +128 -0
  681. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sbp.js +128 -0
  682. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_se-fi.js +128 -0
  683. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_se-no.js +128 -0
  684. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_se-se.js +128 -0
  685. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_se.js +128 -0
  686. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_seh-mz.js +128 -0
  687. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_seh.js +128 -0
  688. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ses-ml.js +128 -0
  689. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ses.js +128 -0
  690. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sg-cf.js +128 -0
  691. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sg.js +128 -0
  692. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_shi-latn-ma.js +128 -0
  693. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_shi-latn.js +128 -0
  694. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_shi-tfng-ma.js +128 -0
  695. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_shi-tfng.js +128 -0
  696. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_shi.js +128 -0
  697. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_si-lk.js +128 -0
  698. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_si.js +128 -0
  699. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sk-sk.js +128 -0
  700. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sk.js +128 -0
  701. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sl-si.js +128 -0
  702. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sl.js +128 -0
  703. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_smn-fi.js +128 -0
  704. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_smn.js +128 -0
  705. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sn-zw.js +128 -0
  706. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sn.js +128 -0
  707. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_so-dj.js +128 -0
  708. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_so-et.js +128 -0
  709. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_so-ke.js +128 -0
  710. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_so-so.js +128 -0
  711. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_so.js +128 -0
  712. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sq-al.js +110 -0
  713. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sq-mk.js +110 -0
  714. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sq-xk.js +110 -0
  715. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sq.js +110 -0
  716. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sr-cyrl-ba.js +128 -0
  717. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sr-cyrl-me.js +128 -0
  718. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sr-cyrl-rs.js +128 -0
  719. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sr-cyrl-xk.js +128 -0
  720. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sr-cyrl.js +128 -0
  721. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sr-latn-ba.js +128 -0
  722. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sr-latn-me.js +128 -0
  723. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sr-latn-rs.js +128 -0
  724. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sr-latn-xk.js +128 -0
  725. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sr-latn.js +128 -0
  726. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sr.js +128 -0
  727. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ss-sz.js +128 -0
  728. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ss-za.js +128 -0
  729. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ss.js +128 -0
  730. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ssy-er.js +128 -0
  731. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ssy.js +128 -0
  732. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_st-ls.js +115 -0
  733. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_st-za.js +115 -0
  734. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_st.js +115 -0
  735. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sv-ax.js +128 -0
  736. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sv-fi.js +128 -0
  737. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sv-se.js +128 -0
  738. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sv.js +128 -0
  739. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sw-cd.js +128 -0
  740. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sw-ke.js +128 -0
  741. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sw-tz.js +128 -0
  742. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sw-ug.js +128 -0
  743. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_sw.js +128 -0
  744. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_swc-cd.js +128 -0
  745. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_swc.js +128 -0
  746. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ta-in.js +110 -0
  747. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ta-lk.js +110 -0
  748. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ta-my.js +110 -0
  749. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ta-sg.js +110 -0
  750. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ta.js +110 -0
  751. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_te-in.js +110 -0
  752. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_te.js +110 -0
  753. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_teo-ke.js +128 -0
  754. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_teo-ug.js +128 -0
  755. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_teo.js +128 -0
  756. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_tg-cyrl-tj.js +115 -0
  757. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_tg-cyrl.js +115 -0
  758. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_tg.js +115 -0
  759. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_th-th.js +110 -0
  760. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_th.js +110 -0
  761. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ti-er.js +128 -0
  762. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ti-et.js +128 -0
  763. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ti.js +128 -0
  764. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_tig-er.js +115 -0
  765. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_tig.js +115 -0
  766. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_tl.js +128 -0
  767. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_tn-bw.js +128 -0
  768. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_tn-za.js +128 -0
  769. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_tn.js +128 -0
  770. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_to-to.js +128 -0
  771. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_to.js +128 -0
  772. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_tr-cy.js +110 -0
  773. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_tr-tr.js +110 -0
  774. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_tr.js +110 -0
  775. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ts-za.js +128 -0
  776. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ts.js +128 -0
  777. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_twq-ne.js +128 -0
  778. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_twq.js +128 -0
  779. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_tzm-latn-ma.js +128 -0
  780. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_tzm-latn.js +128 -0
  781. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_tzm.js +128 -0
  782. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ug-arab-cn.js +128 -0
  783. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ug-arab.js +128 -0
  784. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ug.js +128 -0
  785. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_uk-ua.js +128 -0
  786. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_uk.js +128 -0
  787. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ur-in.js +128 -0
  788. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ur-pk.js +128 -0
  789. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ur.js +128 -0
  790. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_uz-arab-af.js +110 -0
  791. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_uz-arab.js +110 -0
  792. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_uz-cyrl-uz.js +110 -0
  793. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_uz-cyrl.js +110 -0
  794. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_uz-latn-uz.js +110 -0
  795. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_uz-latn.js +110 -0
  796. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_uz.js +110 -0
  797. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_vai-latn-lr.js +128 -0
  798. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_vai-latn.js +128 -0
  799. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_vai-vaii-lr.js +128 -0
  800. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_vai-vaii.js +128 -0
  801. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_vai.js +128 -0
  802. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ve-za.js +128 -0
  803. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_ve.js +128 -0
  804. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_vi-vn.js +110 -0
  805. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_vi.js +110 -0
  806. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_vo-001.js +128 -0
  807. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_vo.js +128 -0
  808. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_vun-tz.js +128 -0
  809. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_vun.js +128 -0
  810. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_wae-ch.js +128 -0
  811. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_wae.js +128 -0
  812. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_wal-et.js +115 -0
  813. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_wal.js +115 -0
  814. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_xh-za.js +115 -0
  815. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_xh.js +115 -0
  816. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_xog-ug.js +128 -0
  817. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_xog.js +128 -0
  818. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_yav-cm.js +128 -0
  819. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_yav.js +128 -0
  820. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_yi-001.js +128 -0
  821. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_yi.js +128 -0
  822. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_yo-bj.js +128 -0
  823. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_yo-ng.js +128 -0
  824. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_yo.js +128 -0
  825. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_zgh-ma.js +128 -0
  826. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_zgh.js +128 -0
  827. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_zh-cn.js +110 -0
  828. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_zh-hans-cn.js +110 -0
  829. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_zh-hans-hk.js +110 -0
  830. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_zh-hans-mo.js +110 -0
  831. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_zh-hans-sg.js +110 -0
  832. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_zh-hans.js +110 -0
  833. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_zh-hant-hk.js +110 -0
  834. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_zh-hant-mo.js +110 -0
  835. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_zh-hant-tw.js +110 -0
  836. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_zh-hant.js +110 -0
  837. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_zh-hk.js +110 -0
  838. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_zh-tw.js +110 -0
  839. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_zh.js +110 -0
  840. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_zu-za.js +110 -0
  841. data/vendor/assets/javascripts/oxymoron/i18n/angular-locale_zu.js +110 -0
  842. data/vendor/assets/javascripts/oxymoron/jquery.min.js +4 -0
  843. data/vendor/assets/javascripts/oxymoron/ng-notify.js +1 -0
  844. data/vendor/assets/javascripts/oxymoron/pace.js +2 -0
  845. data/vendor/assets/javascripts/oxymoron/perfect-scrollbar.js +1588 -0
  846. data/vendor/assets/javascripts/oxymoron/store.js +191 -0
  847. data/vendor/assets/javascripts/oxymoron/underscore.js +1548 -0
  848. data/vendor/assets/stylesheets/.DS_Store +0 -0
  849. data/vendor/assets/stylesheets/oxymoron/md-data-table.css +482 -0
  850. data/vendor/assets/stylesheets/oxymoron/ng-notify.css +40 -0
  851. data/vendor/assets/stylesheets/oxymoron/normalize.css +427 -0
  852. data/vendor/assets/stylesheets/oxymoron/pace.css +41 -0
  853. data/vendor/assets/stylesheets/oxymoron/perfect-scrollbar.css +1 -0
  854. metadata +1004 -0
@@ -0,0 +1,2470 @@
1
+ /**
2
+ * @license AngularJS v1.4.7
3
+ * (c) 2010-2015 Google, Inc. http://angularjs.org
4
+ * License: MIT
5
+ */
6
+ (function(window, angular, undefined) {
7
+
8
+ 'use strict';
9
+
10
+ /**
11
+ * @ngdoc object
12
+ * @name angular.mock
13
+ * @description
14
+ *
15
+ * Namespace from 'angular-mocks.js' which contains testing related code.
16
+ */
17
+ angular.mock = {};
18
+
19
+ /**
20
+ * ! This is a private undocumented service !
21
+ *
22
+ * @name $browser
23
+ *
24
+ * @description
25
+ * This service is a mock implementation of {@link ng.$browser}. It provides fake
26
+ * implementation for commonly used browser apis that are hard to test, e.g. setTimeout, xhr,
27
+ * cookies, etc...
28
+ *
29
+ * The api of this service is the same as that of the real {@link ng.$browser $browser}, except
30
+ * that there are several helper methods available which can be used in tests.
31
+ */
32
+ angular.mock.$BrowserProvider = function() {
33
+ this.$get = function() {
34
+ return new angular.mock.$Browser();
35
+ };
36
+ };
37
+
38
+ angular.mock.$Browser = function() {
39
+ var self = this;
40
+
41
+ this.isMock = true;
42
+ self.$$url = "http://server/";
43
+ self.$$lastUrl = self.$$url; // used by url polling fn
44
+ self.pollFns = [];
45
+
46
+ // TODO(vojta): remove this temporary api
47
+ self.$$completeOutstandingRequest = angular.noop;
48
+ self.$$incOutstandingRequestCount = angular.noop;
49
+
50
+
51
+ // register url polling fn
52
+
53
+ self.onUrlChange = function(listener) {
54
+ self.pollFns.push(
55
+ function() {
56
+ if (self.$$lastUrl !== self.$$url || self.$$state !== self.$$lastState) {
57
+ self.$$lastUrl = self.$$url;
58
+ self.$$lastState = self.$$state;
59
+ listener(self.$$url, self.$$state);
60
+ }
61
+ }
62
+ );
63
+
64
+ return listener;
65
+ };
66
+
67
+ self.$$applicationDestroyed = angular.noop;
68
+ self.$$checkUrlChange = angular.noop;
69
+
70
+ self.deferredFns = [];
71
+ self.deferredNextId = 0;
72
+
73
+ self.defer = function(fn, delay) {
74
+ delay = delay || 0;
75
+ self.deferredFns.push({time:(self.defer.now + delay), fn:fn, id: self.deferredNextId});
76
+ self.deferredFns.sort(function(a, b) { return a.time - b.time;});
77
+ return self.deferredNextId++;
78
+ };
79
+
80
+
81
+ /**
82
+ * @name $browser#defer.now
83
+ *
84
+ * @description
85
+ * Current milliseconds mock time.
86
+ */
87
+ self.defer.now = 0;
88
+
89
+
90
+ self.defer.cancel = function(deferId) {
91
+ var fnIndex;
92
+
93
+ angular.forEach(self.deferredFns, function(fn, index) {
94
+ if (fn.id === deferId) fnIndex = index;
95
+ });
96
+
97
+ if (angular.isDefined(fnIndex)) {
98
+ self.deferredFns.splice(fnIndex, 1);
99
+ return true;
100
+ }
101
+
102
+ return false;
103
+ };
104
+
105
+
106
+ /**
107
+ * @name $browser#defer.flush
108
+ *
109
+ * @description
110
+ * Flushes all pending requests and executes the defer callbacks.
111
+ *
112
+ * @param {number=} number of milliseconds to flush. See {@link #defer.now}
113
+ */
114
+ self.defer.flush = function(delay) {
115
+ if (angular.isDefined(delay)) {
116
+ self.defer.now += delay;
117
+ } else {
118
+ if (self.deferredFns.length) {
119
+ self.defer.now = self.deferredFns[self.deferredFns.length - 1].time;
120
+ } else {
121
+ throw new Error('No deferred tasks to be flushed');
122
+ }
123
+ }
124
+
125
+ while (self.deferredFns.length && self.deferredFns[0].time <= self.defer.now) {
126
+ self.deferredFns.shift().fn();
127
+ }
128
+ };
129
+
130
+ self.$$baseHref = '/';
131
+ self.baseHref = function() {
132
+ return this.$$baseHref;
133
+ };
134
+ };
135
+ angular.mock.$Browser.prototype = {
136
+
137
+ /**
138
+ * @name $browser#poll
139
+ *
140
+ * @description
141
+ * run all fns in pollFns
142
+ */
143
+ poll: function poll() {
144
+ angular.forEach(this.pollFns, function(pollFn) {
145
+ pollFn();
146
+ });
147
+ },
148
+
149
+ url: function(url, replace, state) {
150
+ if (angular.isUndefined(state)) {
151
+ state = null;
152
+ }
153
+ if (url) {
154
+ this.$$url = url;
155
+ // Native pushState serializes & copies the object; simulate it.
156
+ this.$$state = angular.copy(state);
157
+ return this;
158
+ }
159
+
160
+ return this.$$url;
161
+ },
162
+
163
+ state: function() {
164
+ return this.$$state;
165
+ },
166
+
167
+ notifyWhenNoOutstandingRequests: function(fn) {
168
+ fn();
169
+ }
170
+ };
171
+
172
+
173
+ /**
174
+ * @ngdoc provider
175
+ * @name $exceptionHandlerProvider
176
+ *
177
+ * @description
178
+ * Configures the mock implementation of {@link ng.$exceptionHandler} to rethrow or to log errors
179
+ * passed to the `$exceptionHandler`.
180
+ */
181
+
182
+ /**
183
+ * @ngdoc service
184
+ * @name $exceptionHandler
185
+ *
186
+ * @description
187
+ * Mock implementation of {@link ng.$exceptionHandler} that rethrows or logs errors passed
188
+ * to it. See {@link ngMock.$exceptionHandlerProvider $exceptionHandlerProvider} for configuration
189
+ * information.
190
+ *
191
+ *
192
+ * ```js
193
+ * describe('$exceptionHandlerProvider', function() {
194
+ *
195
+ * it('should capture log messages and exceptions', function() {
196
+ *
197
+ * module(function($exceptionHandlerProvider) {
198
+ * $exceptionHandlerProvider.mode('log');
199
+ * });
200
+ *
201
+ * inject(function($log, $exceptionHandler, $timeout) {
202
+ * $timeout(function() { $log.log(1); });
203
+ * $timeout(function() { $log.log(2); throw 'banana peel'; });
204
+ * $timeout(function() { $log.log(3); });
205
+ * expect($exceptionHandler.errors).toEqual([]);
206
+ * expect($log.assertEmpty());
207
+ * $timeout.flush();
208
+ * expect($exceptionHandler.errors).toEqual(['banana peel']);
209
+ * expect($log.log.logs).toEqual([[1], [2], [3]]);
210
+ * });
211
+ * });
212
+ * });
213
+ * ```
214
+ */
215
+
216
+ angular.mock.$ExceptionHandlerProvider = function() {
217
+ var handler;
218
+
219
+ /**
220
+ * @ngdoc method
221
+ * @name $exceptionHandlerProvider#mode
222
+ *
223
+ * @description
224
+ * Sets the logging mode.
225
+ *
226
+ * @param {string} mode Mode of operation, defaults to `rethrow`.
227
+ *
228
+ * - `log`: Sometimes it is desirable to test that an error is thrown, for this case the `log`
229
+ * mode stores an array of errors in `$exceptionHandler.errors`, to allow later
230
+ * assertion of them. See {@link ngMock.$log#assertEmpty assertEmpty()} and
231
+ * {@link ngMock.$log#reset reset()}
232
+ * - `rethrow`: If any errors are passed to the handler in tests, it typically means that there
233
+ * is a bug in the application or test, so this mock will make these tests fail.
234
+ * For any implementations that expect exceptions to be thrown, the `rethrow` mode
235
+ * will also maintain a log of thrown errors.
236
+ */
237
+ this.mode = function(mode) {
238
+
239
+ switch (mode) {
240
+ case 'log':
241
+ case 'rethrow':
242
+ var errors = [];
243
+ handler = function(e) {
244
+ if (arguments.length == 1) {
245
+ errors.push(e);
246
+ } else {
247
+ errors.push([].slice.call(arguments, 0));
248
+ }
249
+ if (mode === "rethrow") {
250
+ throw e;
251
+ }
252
+ };
253
+ handler.errors = errors;
254
+ break;
255
+ default:
256
+ throw new Error("Unknown mode '" + mode + "', only 'log'/'rethrow' modes are allowed!");
257
+ }
258
+ };
259
+
260
+ this.$get = function() {
261
+ return handler;
262
+ };
263
+
264
+ this.mode('rethrow');
265
+ };
266
+
267
+
268
+ /**
269
+ * @ngdoc service
270
+ * @name $log
271
+ *
272
+ * @description
273
+ * Mock implementation of {@link ng.$log} that gathers all logged messages in arrays
274
+ * (one array per logging level). These arrays are exposed as `logs` property of each of the
275
+ * level-specific log function, e.g. for level `error` the array is exposed as `$log.error.logs`.
276
+ *
277
+ */
278
+ angular.mock.$LogProvider = function() {
279
+ var debug = true;
280
+
281
+ function concat(array1, array2, index) {
282
+ return array1.concat(Array.prototype.slice.call(array2, index));
283
+ }
284
+
285
+ this.debugEnabled = function(flag) {
286
+ if (angular.isDefined(flag)) {
287
+ debug = flag;
288
+ return this;
289
+ } else {
290
+ return debug;
291
+ }
292
+ };
293
+
294
+ this.$get = function() {
295
+ var $log = {
296
+ log: function() { $log.log.logs.push(concat([], arguments, 0)); },
297
+ warn: function() { $log.warn.logs.push(concat([], arguments, 0)); },
298
+ info: function() { $log.info.logs.push(concat([], arguments, 0)); },
299
+ error: function() { $log.error.logs.push(concat([], arguments, 0)); },
300
+ debug: function() {
301
+ if (debug) {
302
+ $log.debug.logs.push(concat([], arguments, 0));
303
+ }
304
+ }
305
+ };
306
+
307
+ /**
308
+ * @ngdoc method
309
+ * @name $log#reset
310
+ *
311
+ * @description
312
+ * Reset all of the logging arrays to empty.
313
+ */
314
+ $log.reset = function() {
315
+ /**
316
+ * @ngdoc property
317
+ * @name $log#log.logs
318
+ *
319
+ * @description
320
+ * Array of messages logged using {@link ng.$log#log `log()`}.
321
+ *
322
+ * @example
323
+ * ```js
324
+ * $log.log('Some Log');
325
+ * var first = $log.log.logs.unshift();
326
+ * ```
327
+ */
328
+ $log.log.logs = [];
329
+ /**
330
+ * @ngdoc property
331
+ * @name $log#info.logs
332
+ *
333
+ * @description
334
+ * Array of messages logged using {@link ng.$log#info `info()`}.
335
+ *
336
+ * @example
337
+ * ```js
338
+ * $log.info('Some Info');
339
+ * var first = $log.info.logs.unshift();
340
+ * ```
341
+ */
342
+ $log.info.logs = [];
343
+ /**
344
+ * @ngdoc property
345
+ * @name $log#warn.logs
346
+ *
347
+ * @description
348
+ * Array of messages logged using {@link ng.$log#warn `warn()`}.
349
+ *
350
+ * @example
351
+ * ```js
352
+ * $log.warn('Some Warning');
353
+ * var first = $log.warn.logs.unshift();
354
+ * ```
355
+ */
356
+ $log.warn.logs = [];
357
+ /**
358
+ * @ngdoc property
359
+ * @name $log#error.logs
360
+ *
361
+ * @description
362
+ * Array of messages logged using {@link ng.$log#error `error()`}.
363
+ *
364
+ * @example
365
+ * ```js
366
+ * $log.error('Some Error');
367
+ * var first = $log.error.logs.unshift();
368
+ * ```
369
+ */
370
+ $log.error.logs = [];
371
+ /**
372
+ * @ngdoc property
373
+ * @name $log#debug.logs
374
+ *
375
+ * @description
376
+ * Array of messages logged using {@link ng.$log#debug `debug()`}.
377
+ *
378
+ * @example
379
+ * ```js
380
+ * $log.debug('Some Error');
381
+ * var first = $log.debug.logs.unshift();
382
+ * ```
383
+ */
384
+ $log.debug.logs = [];
385
+ };
386
+
387
+ /**
388
+ * @ngdoc method
389
+ * @name $log#assertEmpty
390
+ *
391
+ * @description
392
+ * Assert that all of the logging methods have no logged messages. If any messages are present,
393
+ * an exception is thrown.
394
+ */
395
+ $log.assertEmpty = function() {
396
+ var errors = [];
397
+ angular.forEach(['error', 'warn', 'info', 'log', 'debug'], function(logLevel) {
398
+ angular.forEach($log[logLevel].logs, function(log) {
399
+ angular.forEach(log, function(logItem) {
400
+ errors.push('MOCK $log (' + logLevel + '): ' + String(logItem) + '\n' +
401
+ (logItem.stack || ''));
402
+ });
403
+ });
404
+ });
405
+ if (errors.length) {
406
+ errors.unshift("Expected $log to be empty! Either a message was logged unexpectedly, or " +
407
+ "an expected log message was not checked and removed:");
408
+ errors.push('');
409
+ throw new Error(errors.join('\n---------\n'));
410
+ }
411
+ };
412
+
413
+ $log.reset();
414
+ return $log;
415
+ };
416
+ };
417
+
418
+
419
+ /**
420
+ * @ngdoc service
421
+ * @name $interval
422
+ *
423
+ * @description
424
+ * Mock implementation of the $interval service.
425
+ *
426
+ * Use {@link ngMock.$interval#flush `$interval.flush(millis)`} to
427
+ * move forward by `millis` milliseconds and trigger any functions scheduled to run in that
428
+ * time.
429
+ *
430
+ * @param {function()} fn A function that should be called repeatedly.
431
+ * @param {number} delay Number of milliseconds between each function call.
432
+ * @param {number=} [count=0] Number of times to repeat. If not set, or 0, will repeat
433
+ * indefinitely.
434
+ * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise
435
+ * will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block.
436
+ * @param {...*=} Pass additional parameters to the executed function.
437
+ * @returns {promise} A promise which will be notified on each iteration.
438
+ */
439
+ angular.mock.$IntervalProvider = function() {
440
+ this.$get = ['$browser', '$rootScope', '$q', '$$q',
441
+ function($browser, $rootScope, $q, $$q) {
442
+ var repeatFns = [],
443
+ nextRepeatId = 0,
444
+ now = 0;
445
+
446
+ var $interval = function(fn, delay, count, invokeApply) {
447
+ var hasParams = arguments.length > 4,
448
+ args = hasParams ? Array.prototype.slice.call(arguments, 4) : [],
449
+ iteration = 0,
450
+ skipApply = (angular.isDefined(invokeApply) && !invokeApply),
451
+ deferred = (skipApply ? $$q : $q).defer(),
452
+ promise = deferred.promise;
453
+
454
+ count = (angular.isDefined(count)) ? count : 0;
455
+ promise.then(null, null, (!hasParams) ? fn : function() {
456
+ fn.apply(null, args);
457
+ });
458
+
459
+ promise.$$intervalId = nextRepeatId;
460
+
461
+ function tick() {
462
+ deferred.notify(iteration++);
463
+
464
+ if (count > 0 && iteration >= count) {
465
+ var fnIndex;
466
+ deferred.resolve(iteration);
467
+
468
+ angular.forEach(repeatFns, function(fn, index) {
469
+ if (fn.id === promise.$$intervalId) fnIndex = index;
470
+ });
471
+
472
+ if (angular.isDefined(fnIndex)) {
473
+ repeatFns.splice(fnIndex, 1);
474
+ }
475
+ }
476
+
477
+ if (skipApply) {
478
+ $browser.defer.flush();
479
+ } else {
480
+ $rootScope.$apply();
481
+ }
482
+ }
483
+
484
+ repeatFns.push({
485
+ nextTime:(now + delay),
486
+ delay: delay,
487
+ fn: tick,
488
+ id: nextRepeatId,
489
+ deferred: deferred
490
+ });
491
+ repeatFns.sort(function(a, b) { return a.nextTime - b.nextTime;});
492
+
493
+ nextRepeatId++;
494
+ return promise;
495
+ };
496
+ /**
497
+ * @ngdoc method
498
+ * @name $interval#cancel
499
+ *
500
+ * @description
501
+ * Cancels a task associated with the `promise`.
502
+ *
503
+ * @param {promise} promise A promise from calling the `$interval` function.
504
+ * @returns {boolean} Returns `true` if the task was successfully cancelled.
505
+ */
506
+ $interval.cancel = function(promise) {
507
+ if (!promise) return false;
508
+ var fnIndex;
509
+
510
+ angular.forEach(repeatFns, function(fn, index) {
511
+ if (fn.id === promise.$$intervalId) fnIndex = index;
512
+ });
513
+
514
+ if (angular.isDefined(fnIndex)) {
515
+ repeatFns[fnIndex].deferred.reject('canceled');
516
+ repeatFns.splice(fnIndex, 1);
517
+ return true;
518
+ }
519
+
520
+ return false;
521
+ };
522
+
523
+ /**
524
+ * @ngdoc method
525
+ * @name $interval#flush
526
+ * @description
527
+ *
528
+ * Runs interval tasks scheduled to be run in the next `millis` milliseconds.
529
+ *
530
+ * @param {number=} millis maximum timeout amount to flush up until.
531
+ *
532
+ * @return {number} The amount of time moved forward.
533
+ */
534
+ $interval.flush = function(millis) {
535
+ now += millis;
536
+ while (repeatFns.length && repeatFns[0].nextTime <= now) {
537
+ var task = repeatFns[0];
538
+ task.fn();
539
+ task.nextTime += task.delay;
540
+ repeatFns.sort(function(a, b) { return a.nextTime - b.nextTime;});
541
+ }
542
+ return millis;
543
+ };
544
+
545
+ return $interval;
546
+ }];
547
+ };
548
+
549
+
550
+ /* jshint -W101 */
551
+ /* The R_ISO8061_STR regex is never going to fit into the 100 char limit!
552
+ * This directive should go inside the anonymous function but a bug in JSHint means that it would
553
+ * not be enacted early enough to prevent the warning.
554
+ */
555
+ var R_ISO8061_STR = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?:\:?(\d\d)(?:\:?(\d\d)(?:\.(\d{3}))?)?)?(Z|([+-])(\d\d):?(\d\d)))?$/;
556
+
557
+ function jsonStringToDate(string) {
558
+ var match;
559
+ if (match = string.match(R_ISO8061_STR)) {
560
+ var date = new Date(0),
561
+ tzHour = 0,
562
+ tzMin = 0;
563
+ if (match[9]) {
564
+ tzHour = toInt(match[9] + match[10]);
565
+ tzMin = toInt(match[9] + match[11]);
566
+ }
567
+ date.setUTCFullYear(toInt(match[1]), toInt(match[2]) - 1, toInt(match[3]));
568
+ date.setUTCHours(toInt(match[4] || 0) - tzHour,
569
+ toInt(match[5] || 0) - tzMin,
570
+ toInt(match[6] || 0),
571
+ toInt(match[7] || 0));
572
+ return date;
573
+ }
574
+ return string;
575
+ }
576
+
577
+ function toInt(str) {
578
+ return parseInt(str, 10);
579
+ }
580
+
581
+ function padNumber(num, digits, trim) {
582
+ var neg = '';
583
+ if (num < 0) {
584
+ neg = '-';
585
+ num = -num;
586
+ }
587
+ num = '' + num;
588
+ while (num.length < digits) num = '0' + num;
589
+ if (trim) {
590
+ num = num.substr(num.length - digits);
591
+ }
592
+ return neg + num;
593
+ }
594
+
595
+
596
+ /**
597
+ * @ngdoc type
598
+ * @name angular.mock.TzDate
599
+ * @description
600
+ *
601
+ * *NOTE*: this is not an injectable instance, just a globally available mock class of `Date`.
602
+ *
603
+ * Mock of the Date type which has its timezone specified via constructor arg.
604
+ *
605
+ * The main purpose is to create Date-like instances with timezone fixed to the specified timezone
606
+ * offset, so that we can test code that depends on local timezone settings without dependency on
607
+ * the time zone settings of the machine where the code is running.
608
+ *
609
+ * @param {number} offset Offset of the *desired* timezone in hours (fractions will be honored)
610
+ * @param {(number|string)} timestamp Timestamp representing the desired time in *UTC*
611
+ *
612
+ * @example
613
+ * !!!! WARNING !!!!!
614
+ * This is not a complete Date object so only methods that were implemented can be called safely.
615
+ * To make matters worse, TzDate instances inherit stuff from Date via a prototype.
616
+ *
617
+ * We do our best to intercept calls to "unimplemented" methods, but since the list of methods is
618
+ * incomplete we might be missing some non-standard methods. This can result in errors like:
619
+ * "Date.prototype.foo called on incompatible Object".
620
+ *
621
+ * ```js
622
+ * var newYearInBratislava = new TzDate(-1, '2009-12-31T23:00:00Z');
623
+ * newYearInBratislava.getTimezoneOffset() => -60;
624
+ * newYearInBratislava.getFullYear() => 2010;
625
+ * newYearInBratislava.getMonth() => 0;
626
+ * newYearInBratislava.getDate() => 1;
627
+ * newYearInBratislava.getHours() => 0;
628
+ * newYearInBratislava.getMinutes() => 0;
629
+ * newYearInBratislava.getSeconds() => 0;
630
+ * ```
631
+ *
632
+ */
633
+ angular.mock.TzDate = function(offset, timestamp) {
634
+ var self = new Date(0);
635
+ if (angular.isString(timestamp)) {
636
+ var tsStr = timestamp;
637
+
638
+ self.origDate = jsonStringToDate(timestamp);
639
+
640
+ timestamp = self.origDate.getTime();
641
+ if (isNaN(timestamp)) {
642
+ throw {
643
+ name: "Illegal Argument",
644
+ message: "Arg '" + tsStr + "' passed into TzDate constructor is not a valid date string"
645
+ };
646
+ }
647
+ } else {
648
+ self.origDate = new Date(timestamp);
649
+ }
650
+
651
+ var localOffset = new Date(timestamp).getTimezoneOffset();
652
+ self.offsetDiff = localOffset * 60 * 1000 - offset * 1000 * 60 * 60;
653
+ self.date = new Date(timestamp + self.offsetDiff);
654
+
655
+ self.getTime = function() {
656
+ return self.date.getTime() - self.offsetDiff;
657
+ };
658
+
659
+ self.toLocaleDateString = function() {
660
+ return self.date.toLocaleDateString();
661
+ };
662
+
663
+ self.getFullYear = function() {
664
+ return self.date.getFullYear();
665
+ };
666
+
667
+ self.getMonth = function() {
668
+ return self.date.getMonth();
669
+ };
670
+
671
+ self.getDate = function() {
672
+ return self.date.getDate();
673
+ };
674
+
675
+ self.getHours = function() {
676
+ return self.date.getHours();
677
+ };
678
+
679
+ self.getMinutes = function() {
680
+ return self.date.getMinutes();
681
+ };
682
+
683
+ self.getSeconds = function() {
684
+ return self.date.getSeconds();
685
+ };
686
+
687
+ self.getMilliseconds = function() {
688
+ return self.date.getMilliseconds();
689
+ };
690
+
691
+ self.getTimezoneOffset = function() {
692
+ return offset * 60;
693
+ };
694
+
695
+ self.getUTCFullYear = function() {
696
+ return self.origDate.getUTCFullYear();
697
+ };
698
+
699
+ self.getUTCMonth = function() {
700
+ return self.origDate.getUTCMonth();
701
+ };
702
+
703
+ self.getUTCDate = function() {
704
+ return self.origDate.getUTCDate();
705
+ };
706
+
707
+ self.getUTCHours = function() {
708
+ return self.origDate.getUTCHours();
709
+ };
710
+
711
+ self.getUTCMinutes = function() {
712
+ return self.origDate.getUTCMinutes();
713
+ };
714
+
715
+ self.getUTCSeconds = function() {
716
+ return self.origDate.getUTCSeconds();
717
+ };
718
+
719
+ self.getUTCMilliseconds = function() {
720
+ return self.origDate.getUTCMilliseconds();
721
+ };
722
+
723
+ self.getDay = function() {
724
+ return self.date.getDay();
725
+ };
726
+
727
+ // provide this method only on browsers that already have it
728
+ if (self.toISOString) {
729
+ self.toISOString = function() {
730
+ return padNumber(self.origDate.getUTCFullYear(), 4) + '-' +
731
+ padNumber(self.origDate.getUTCMonth() + 1, 2) + '-' +
732
+ padNumber(self.origDate.getUTCDate(), 2) + 'T' +
733
+ padNumber(self.origDate.getUTCHours(), 2) + ':' +
734
+ padNumber(self.origDate.getUTCMinutes(), 2) + ':' +
735
+ padNumber(self.origDate.getUTCSeconds(), 2) + '.' +
736
+ padNumber(self.origDate.getUTCMilliseconds(), 3) + 'Z';
737
+ };
738
+ }
739
+
740
+ //hide all methods not implemented in this mock that the Date prototype exposes
741
+ var unimplementedMethods = ['getUTCDay',
742
+ 'getYear', 'setDate', 'setFullYear', 'setHours', 'setMilliseconds',
743
+ 'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear',
744
+ 'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds',
745
+ 'setYear', 'toDateString', 'toGMTString', 'toJSON', 'toLocaleFormat', 'toLocaleString',
746
+ 'toLocaleTimeString', 'toSource', 'toString', 'toTimeString', 'toUTCString', 'valueOf'];
747
+
748
+ angular.forEach(unimplementedMethods, function(methodName) {
749
+ self[methodName] = function() {
750
+ throw new Error("Method '" + methodName + "' is not implemented in the TzDate mock");
751
+ };
752
+ });
753
+
754
+ return self;
755
+ };
756
+
757
+ //make "tzDateInstance instanceof Date" return true
758
+ angular.mock.TzDate.prototype = Date.prototype;
759
+ /* jshint +W101 */
760
+
761
+ angular.mock.animate = angular.module('ngAnimateMock', ['ng'])
762
+
763
+ .config(['$provide', function($provide) {
764
+
765
+ $provide.factory('$$forceReflow', function() {
766
+ function reflowFn() {
767
+ reflowFn.totalReflows++;
768
+ }
769
+ reflowFn.totalReflows = 0;
770
+ return reflowFn;
771
+ });
772
+
773
+ $provide.factory('$$animateAsyncRun', function() {
774
+ var queue = [];
775
+ var queueFn = function() {
776
+ return function(fn) {
777
+ queue.push(fn);
778
+ };
779
+ };
780
+ queueFn.flush = function() {
781
+ if (queue.length === 0) return false;
782
+
783
+ for (var i = 0; i < queue.length; i++) {
784
+ queue[i]();
785
+ }
786
+ queue = [];
787
+
788
+ return true;
789
+ };
790
+ return queueFn;
791
+ });
792
+
793
+ $provide.decorator('$animate', ['$delegate', '$timeout', '$browser', '$$rAF',
794
+ '$$forceReflow', '$$animateAsyncRun', '$rootScope',
795
+ function($delegate, $timeout, $browser, $$rAF,
796
+ $$forceReflow, $$animateAsyncRun, $rootScope) {
797
+ var animate = {
798
+ queue: [],
799
+ cancel: $delegate.cancel,
800
+ on: $delegate.on,
801
+ off: $delegate.off,
802
+ pin: $delegate.pin,
803
+ get reflows() {
804
+ return $$forceReflow.totalReflows;
805
+ },
806
+ enabled: $delegate.enabled,
807
+ flush: function() {
808
+ $rootScope.$digest();
809
+
810
+ var doNextRun, somethingFlushed = false;
811
+ do {
812
+ doNextRun = false;
813
+
814
+ if ($$rAF.queue.length) {
815
+ $$rAF.flush();
816
+ doNextRun = somethingFlushed = true;
817
+ }
818
+
819
+ if ($$animateAsyncRun.flush()) {
820
+ doNextRun = somethingFlushed = true;
821
+ }
822
+ } while (doNextRun);
823
+
824
+ if (!somethingFlushed) {
825
+ throw new Error('No pending animations ready to be closed or flushed');
826
+ }
827
+
828
+ $rootScope.$digest();
829
+ }
830
+ };
831
+
832
+ angular.forEach(
833
+ ['animate','enter','leave','move','addClass','removeClass','setClass'], function(method) {
834
+ animate[method] = function() {
835
+ animate.queue.push({
836
+ event: method,
837
+ element: arguments[0],
838
+ options: arguments[arguments.length - 1],
839
+ args: arguments
840
+ });
841
+ return $delegate[method].apply($delegate, arguments);
842
+ };
843
+ });
844
+
845
+ return animate;
846
+ }]);
847
+
848
+ }]);
849
+
850
+
851
+ /**
852
+ * @ngdoc function
853
+ * @name angular.mock.dump
854
+ * @description
855
+ *
856
+ * *NOTE*: this is not an injectable instance, just a globally available function.
857
+ *
858
+ * Method for serializing common angular objects (scope, elements, etc..) into strings, useful for
859
+ * debugging.
860
+ *
861
+ * This method is also available on window, where it can be used to display objects on debug
862
+ * console.
863
+ *
864
+ * @param {*} object - any object to turn into string.
865
+ * @return {string} a serialized string of the argument
866
+ */
867
+ angular.mock.dump = function(object) {
868
+ return serialize(object);
869
+
870
+ function serialize(object) {
871
+ var out;
872
+
873
+ if (angular.isElement(object)) {
874
+ object = angular.element(object);
875
+ out = angular.element('<div></div>');
876
+ angular.forEach(object, function(element) {
877
+ out.append(angular.element(element).clone());
878
+ });
879
+ out = out.html();
880
+ } else if (angular.isArray(object)) {
881
+ out = [];
882
+ angular.forEach(object, function(o) {
883
+ out.push(serialize(o));
884
+ });
885
+ out = '[ ' + out.join(', ') + ' ]';
886
+ } else if (angular.isObject(object)) {
887
+ if (angular.isFunction(object.$eval) && angular.isFunction(object.$apply)) {
888
+ out = serializeScope(object);
889
+ } else if (object instanceof Error) {
890
+ out = object.stack || ('' + object.name + ': ' + object.message);
891
+ } else {
892
+ // TODO(i): this prevents methods being logged,
893
+ // we should have a better way to serialize objects
894
+ out = angular.toJson(object, true);
895
+ }
896
+ } else {
897
+ out = String(object);
898
+ }
899
+
900
+ return out;
901
+ }
902
+
903
+ function serializeScope(scope, offset) {
904
+ offset = offset || ' ';
905
+ var log = [offset + 'Scope(' + scope.$id + '): {'];
906
+ for (var key in scope) {
907
+ if (Object.prototype.hasOwnProperty.call(scope, key) && !key.match(/^(\$|this)/)) {
908
+ log.push(' ' + key + ': ' + angular.toJson(scope[key]));
909
+ }
910
+ }
911
+ var child = scope.$$childHead;
912
+ while (child) {
913
+ log.push(serializeScope(child, offset + ' '));
914
+ child = child.$$nextSibling;
915
+ }
916
+ log.push('}');
917
+ return log.join('\n' + offset);
918
+ }
919
+ };
920
+
921
+ /**
922
+ * @ngdoc service
923
+ * @name $httpBackend
924
+ * @description
925
+ * Fake HTTP backend implementation suitable for unit testing applications that use the
926
+ * {@link ng.$http $http service}.
927
+ *
928
+ * *Note*: For fake HTTP backend implementation suitable for end-to-end testing or backend-less
929
+ * development please see {@link ngMockE2E.$httpBackend e2e $httpBackend mock}.
930
+ *
931
+ * During unit testing, we want our unit tests to run quickly and have no external dependencies so
932
+ * we don’t want to send [XHR](https://developer.mozilla.org/en/xmlhttprequest) or
933
+ * [JSONP](http://en.wikipedia.org/wiki/JSONP) requests to a real server. All we really need is
934
+ * to verify whether a certain request has been sent or not, or alternatively just let the
935
+ * application make requests, respond with pre-trained responses and assert that the end result is
936
+ * what we expect it to be.
937
+ *
938
+ * This mock implementation can be used to respond with static or dynamic responses via the
939
+ * `expect` and `when` apis and their shortcuts (`expectGET`, `whenPOST`, etc).
940
+ *
941
+ * When an Angular application needs some data from a server, it calls the $http service, which
942
+ * sends the request to a real server using $httpBackend service. With dependency injection, it is
943
+ * easy to inject $httpBackend mock (which has the same API as $httpBackend) and use it to verify
944
+ * the requests and respond with some testing data without sending a request to a real server.
945
+ *
946
+ * There are two ways to specify what test data should be returned as http responses by the mock
947
+ * backend when the code under test makes http requests:
948
+ *
949
+ * - `$httpBackend.expect` - specifies a request expectation
950
+ * - `$httpBackend.when` - specifies a backend definition
951
+ *
952
+ *
953
+ * # Request Expectations vs Backend Definitions
954
+ *
955
+ * Request expectations provide a way to make assertions about requests made by the application and
956
+ * to define responses for those requests. The test will fail if the expected requests are not made
957
+ * or they are made in the wrong order.
958
+ *
959
+ * Backend definitions allow you to define a fake backend for your application which doesn't assert
960
+ * if a particular request was made or not, it just returns a trained response if a request is made.
961
+ * The test will pass whether or not the request gets made during testing.
962
+ *
963
+ *
964
+ * <table class="table">
965
+ * <tr><th width="220px"></th><th>Request expectations</th><th>Backend definitions</th></tr>
966
+ * <tr>
967
+ * <th>Syntax</th>
968
+ * <td>.expect(...).respond(...)</td>
969
+ * <td>.when(...).respond(...)</td>
970
+ * </tr>
971
+ * <tr>
972
+ * <th>Typical usage</th>
973
+ * <td>strict unit tests</td>
974
+ * <td>loose (black-box) unit testing</td>
975
+ * </tr>
976
+ * <tr>
977
+ * <th>Fulfills multiple requests</th>
978
+ * <td>NO</td>
979
+ * <td>YES</td>
980
+ * </tr>
981
+ * <tr>
982
+ * <th>Order of requests matters</th>
983
+ * <td>YES</td>
984
+ * <td>NO</td>
985
+ * </tr>
986
+ * <tr>
987
+ * <th>Request required</th>
988
+ * <td>YES</td>
989
+ * <td>NO</td>
990
+ * </tr>
991
+ * <tr>
992
+ * <th>Response required</th>
993
+ * <td>optional (see below)</td>
994
+ * <td>YES</td>
995
+ * </tr>
996
+ * </table>
997
+ *
998
+ * In cases where both backend definitions and request expectations are specified during unit
999
+ * testing, the request expectations are evaluated first.
1000
+ *
1001
+ * If a request expectation has no response specified, the algorithm will search your backend
1002
+ * definitions for an appropriate response.
1003
+ *
1004
+ * If a request didn't match any expectation or if the expectation doesn't have the response
1005
+ * defined, the backend definitions are evaluated in sequential order to see if any of them match
1006
+ * the request. The response from the first matched definition is returned.
1007
+ *
1008
+ *
1009
+ * # Flushing HTTP requests
1010
+ *
1011
+ * The $httpBackend used in production always responds to requests asynchronously. If we preserved
1012
+ * this behavior in unit testing, we'd have to create async unit tests, which are hard to write,
1013
+ * to follow and to maintain. But neither can the testing mock respond synchronously; that would
1014
+ * change the execution of the code under test. For this reason, the mock $httpBackend has a
1015
+ * `flush()` method, which allows the test to explicitly flush pending requests. This preserves
1016
+ * the async api of the backend, while allowing the test to execute synchronously.
1017
+ *
1018
+ *
1019
+ * # Unit testing with mock $httpBackend
1020
+ * The following code shows how to setup and use the mock backend when unit testing a controller.
1021
+ * First we create the controller under test:
1022
+ *
1023
+ ```js
1024
+ // The module code
1025
+ angular
1026
+ .module('MyApp', [])
1027
+ .controller('MyController', MyController);
1028
+
1029
+ // The controller code
1030
+ function MyController($scope, $http) {
1031
+ var authToken;
1032
+
1033
+ $http.get('/auth.py').success(function(data, status, headers) {
1034
+ authToken = headers('A-Token');
1035
+ $scope.user = data;
1036
+ });
1037
+
1038
+ $scope.saveMessage = function(message) {
1039
+ var headers = { 'Authorization': authToken };
1040
+ $scope.status = 'Saving...';
1041
+
1042
+ $http.post('/add-msg.py', message, { headers: headers } ).success(function(response) {
1043
+ $scope.status = '';
1044
+ }).error(function() {
1045
+ $scope.status = 'Failed...';
1046
+ });
1047
+ };
1048
+ }
1049
+ ```
1050
+ *
1051
+ * Now we setup the mock backend and create the test specs:
1052
+ *
1053
+ ```js
1054
+ // testing controller
1055
+ describe('MyController', function() {
1056
+ var $httpBackend, $rootScope, createController, authRequestHandler;
1057
+
1058
+ // Set up the module
1059
+ beforeEach(module('MyApp'));
1060
+
1061
+ beforeEach(inject(function($injector) {
1062
+ // Set up the mock http service responses
1063
+ $httpBackend = $injector.get('$httpBackend');
1064
+ // backend definition common for all tests
1065
+ authRequestHandler = $httpBackend.when('GET', '/auth.py')
1066
+ .respond({userId: 'userX'}, {'A-Token': 'xxx'});
1067
+
1068
+ // Get hold of a scope (i.e. the root scope)
1069
+ $rootScope = $injector.get('$rootScope');
1070
+ // The $controller service is used to create instances of controllers
1071
+ var $controller = $injector.get('$controller');
1072
+
1073
+ createController = function() {
1074
+ return $controller('MyController', {'$scope' : $rootScope });
1075
+ };
1076
+ }));
1077
+
1078
+
1079
+ afterEach(function() {
1080
+ $httpBackend.verifyNoOutstandingExpectation();
1081
+ $httpBackend.verifyNoOutstandingRequest();
1082
+ });
1083
+
1084
+
1085
+ it('should fetch authentication token', function() {
1086
+ $httpBackend.expectGET('/auth.py');
1087
+ var controller = createController();
1088
+ $httpBackend.flush();
1089
+ });
1090
+
1091
+
1092
+ it('should fail authentication', function() {
1093
+
1094
+ // Notice how you can change the response even after it was set
1095
+ authRequestHandler.respond(401, '');
1096
+
1097
+ $httpBackend.expectGET('/auth.py');
1098
+ var controller = createController();
1099
+ $httpBackend.flush();
1100
+ expect($rootScope.status).toBe('Failed...');
1101
+ });
1102
+
1103
+
1104
+ it('should send msg to server', function() {
1105
+ var controller = createController();
1106
+ $httpBackend.flush();
1107
+
1108
+ // now you don’t care about the authentication, but
1109
+ // the controller will still send the request and
1110
+ // $httpBackend will respond without you having to
1111
+ // specify the expectation and response for this request
1112
+
1113
+ $httpBackend.expectPOST('/add-msg.py', 'message content').respond(201, '');
1114
+ $rootScope.saveMessage('message content');
1115
+ expect($rootScope.status).toBe('Saving...');
1116
+ $httpBackend.flush();
1117
+ expect($rootScope.status).toBe('');
1118
+ });
1119
+
1120
+
1121
+ it('should send auth header', function() {
1122
+ var controller = createController();
1123
+ $httpBackend.flush();
1124
+
1125
+ $httpBackend.expectPOST('/add-msg.py', undefined, function(headers) {
1126
+ // check if the header was sent, if it wasn't the expectation won't
1127
+ // match the request and the test will fail
1128
+ return headers['Authorization'] == 'xxx';
1129
+ }).respond(201, '');
1130
+
1131
+ $rootScope.saveMessage('whatever');
1132
+ $httpBackend.flush();
1133
+ });
1134
+ });
1135
+ ```
1136
+ */
1137
+ angular.mock.$HttpBackendProvider = function() {
1138
+ this.$get = ['$rootScope', '$timeout', createHttpBackendMock];
1139
+ };
1140
+
1141
+ /**
1142
+ * General factory function for $httpBackend mock.
1143
+ * Returns instance for unit testing (when no arguments specified):
1144
+ * - passing through is disabled
1145
+ * - auto flushing is disabled
1146
+ *
1147
+ * Returns instance for e2e testing (when `$delegate` and `$browser` specified):
1148
+ * - passing through (delegating request to real backend) is enabled
1149
+ * - auto flushing is enabled
1150
+ *
1151
+ * @param {Object=} $delegate Real $httpBackend instance (allow passing through if specified)
1152
+ * @param {Object=} $browser Auto-flushing enabled if specified
1153
+ * @return {Object} Instance of $httpBackend mock
1154
+ */
1155
+ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
1156
+ var definitions = [],
1157
+ expectations = [],
1158
+ responses = [],
1159
+ responsesPush = angular.bind(responses, responses.push),
1160
+ copy = angular.copy;
1161
+
1162
+ function createResponse(status, data, headers, statusText) {
1163
+ if (angular.isFunction(status)) return status;
1164
+
1165
+ return function() {
1166
+ return angular.isNumber(status)
1167
+ ? [status, data, headers, statusText]
1168
+ : [200, status, data, headers];
1169
+ };
1170
+ }
1171
+
1172
+ // TODO(vojta): change params to: method, url, data, headers, callback
1173
+ function $httpBackend(method, url, data, callback, headers, timeout, withCredentials) {
1174
+ var xhr = new MockXhr(),
1175
+ expectation = expectations[0],
1176
+ wasExpected = false;
1177
+
1178
+ function prettyPrint(data) {
1179
+ return (angular.isString(data) || angular.isFunction(data) || data instanceof RegExp)
1180
+ ? data
1181
+ : angular.toJson(data);
1182
+ }
1183
+
1184
+ function wrapResponse(wrapped) {
1185
+ if (!$browser && timeout) {
1186
+ timeout.then ? timeout.then(handleTimeout) : $timeout(handleTimeout, timeout);
1187
+ }
1188
+
1189
+ return handleResponse;
1190
+
1191
+ function handleResponse() {
1192
+ var response = wrapped.response(method, url, data, headers);
1193
+ xhr.$$respHeaders = response[2];
1194
+ callback(copy(response[0]), copy(response[1]), xhr.getAllResponseHeaders(),
1195
+ copy(response[3] || ''));
1196
+ }
1197
+
1198
+ function handleTimeout() {
1199
+ for (var i = 0, ii = responses.length; i < ii; i++) {
1200
+ if (responses[i] === handleResponse) {
1201
+ responses.splice(i, 1);
1202
+ callback(-1, undefined, '');
1203
+ break;
1204
+ }
1205
+ }
1206
+ }
1207
+ }
1208
+
1209
+ if (expectation && expectation.match(method, url)) {
1210
+ if (!expectation.matchData(data)) {
1211
+ throw new Error('Expected ' + expectation + ' with different data\n' +
1212
+ 'EXPECTED: ' + prettyPrint(expectation.data) + '\nGOT: ' + data);
1213
+ }
1214
+
1215
+ if (!expectation.matchHeaders(headers)) {
1216
+ throw new Error('Expected ' + expectation + ' with different headers\n' +
1217
+ 'EXPECTED: ' + prettyPrint(expectation.headers) + '\nGOT: ' +
1218
+ prettyPrint(headers));
1219
+ }
1220
+
1221
+ expectations.shift();
1222
+
1223
+ if (expectation.response) {
1224
+ responses.push(wrapResponse(expectation));
1225
+ return;
1226
+ }
1227
+ wasExpected = true;
1228
+ }
1229
+
1230
+ var i = -1, definition;
1231
+ while ((definition = definitions[++i])) {
1232
+ if (definition.match(method, url, data, headers || {})) {
1233
+ if (definition.response) {
1234
+ // if $browser specified, we do auto flush all requests
1235
+ ($browser ? $browser.defer : responsesPush)(wrapResponse(definition));
1236
+ } else if (definition.passThrough) {
1237
+ $delegate(method, url, data, callback, headers, timeout, withCredentials);
1238
+ } else throw new Error('No response defined !');
1239
+ return;
1240
+ }
1241
+ }
1242
+ throw wasExpected ?
1243
+ new Error('No response defined !') :
1244
+ new Error('Unexpected request: ' + method + ' ' + url + '\n' +
1245
+ (expectation ? 'Expected ' + expectation : 'No more request expected'));
1246
+ }
1247
+
1248
+ /**
1249
+ * @ngdoc method
1250
+ * @name $httpBackend#when
1251
+ * @description
1252
+ * Creates a new backend definition.
1253
+ *
1254
+ * @param {string} method HTTP method.
1255
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
1256
+ * and returns true if the url matches the current definition.
1257
+ * @param {(string|RegExp|function(string))=} data HTTP request body or function that receives
1258
+ * data string and returns true if the data is as expected.
1259
+ * @param {(Object|function(Object))=} headers HTTP headers or function that receives http header
1260
+ * object and returns true if the headers match the current definition.
1261
+ * @returns {requestHandler} Returns an object with `respond` method that controls how a matched
1262
+ * request is handled. You can save this object for later use and invoke `respond` again in
1263
+ * order to change how a matched request is handled.
1264
+ *
1265
+ * - respond –
1266
+ * `{function([status,] data[, headers, statusText])
1267
+ * | function(function(method, url, data, headers)}`
1268
+ * – The respond method takes a set of static data to be returned or a function that can
1269
+ * return an array containing response status (number), response data (string), response
1270
+ * headers (Object), and the text for the status (string). The respond method returns the
1271
+ * `requestHandler` object for possible overrides.
1272
+ */
1273
+ $httpBackend.when = function(method, url, data, headers) {
1274
+ var definition = new MockHttpExpectation(method, url, data, headers),
1275
+ chain = {
1276
+ respond: function(status, data, headers, statusText) {
1277
+ definition.passThrough = undefined;
1278
+ definition.response = createResponse(status, data, headers, statusText);
1279
+ return chain;
1280
+ }
1281
+ };
1282
+
1283
+ if ($browser) {
1284
+ chain.passThrough = function() {
1285
+ definition.response = undefined;
1286
+ definition.passThrough = true;
1287
+ return chain;
1288
+ };
1289
+ }
1290
+
1291
+ definitions.push(definition);
1292
+ return chain;
1293
+ };
1294
+
1295
+ /**
1296
+ * @ngdoc method
1297
+ * @name $httpBackend#whenGET
1298
+ * @description
1299
+ * Creates a new backend definition for GET requests. For more info see `when()`.
1300
+ *
1301
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
1302
+ * and returns true if the url matches the current definition.
1303
+ * @param {(Object|function(Object))=} headers HTTP headers.
1304
+ * @returns {requestHandler} Returns an object with `respond` method that controls how a matched
1305
+ * request is handled. You can save this object for later use and invoke `respond` again in
1306
+ * order to change how a matched request is handled.
1307
+ */
1308
+
1309
+ /**
1310
+ * @ngdoc method
1311
+ * @name $httpBackend#whenHEAD
1312
+ * @description
1313
+ * Creates a new backend definition for HEAD requests. For more info see `when()`.
1314
+ *
1315
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
1316
+ * and returns true if the url matches the current definition.
1317
+ * @param {(Object|function(Object))=} headers HTTP headers.
1318
+ * @returns {requestHandler} Returns an object with `respond` method that controls how a matched
1319
+ * request is handled. You can save this object for later use and invoke `respond` again in
1320
+ * order to change how a matched request is handled.
1321
+ */
1322
+
1323
+ /**
1324
+ * @ngdoc method
1325
+ * @name $httpBackend#whenDELETE
1326
+ * @description
1327
+ * Creates a new backend definition for DELETE requests. For more info see `when()`.
1328
+ *
1329
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
1330
+ * and returns true if the url matches the current definition.
1331
+ * @param {(Object|function(Object))=} headers HTTP headers.
1332
+ * @returns {requestHandler} Returns an object with `respond` method that controls how a matched
1333
+ * request is handled. You can save this object for later use and invoke `respond` again in
1334
+ * order to change how a matched request is handled.
1335
+ */
1336
+
1337
+ /**
1338
+ * @ngdoc method
1339
+ * @name $httpBackend#whenPOST
1340
+ * @description
1341
+ * Creates a new backend definition for POST requests. For more info see `when()`.
1342
+ *
1343
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
1344
+ * and returns true if the url matches the current definition.
1345
+ * @param {(string|RegExp|function(string))=} data HTTP request body or function that receives
1346
+ * data string and returns true if the data is as expected.
1347
+ * @param {(Object|function(Object))=} headers HTTP headers.
1348
+ * @returns {requestHandler} Returns an object with `respond` method that controls how a matched
1349
+ * request is handled. You can save this object for later use and invoke `respond` again in
1350
+ * order to change how a matched request is handled.
1351
+ */
1352
+
1353
+ /**
1354
+ * @ngdoc method
1355
+ * @name $httpBackend#whenPUT
1356
+ * @description
1357
+ * Creates a new backend definition for PUT requests. For more info see `when()`.
1358
+ *
1359
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
1360
+ * and returns true if the url matches the current definition.
1361
+ * @param {(string|RegExp|function(string))=} data HTTP request body or function that receives
1362
+ * data string and returns true if the data is as expected.
1363
+ * @param {(Object|function(Object))=} headers HTTP headers.
1364
+ * @returns {requestHandler} Returns an object with `respond` method that controls how a matched
1365
+ * request is handled. You can save this object for later use and invoke `respond` again in
1366
+ * order to change how a matched request is handled.
1367
+ */
1368
+
1369
+ /**
1370
+ * @ngdoc method
1371
+ * @name $httpBackend#whenJSONP
1372
+ * @description
1373
+ * Creates a new backend definition for JSONP requests. For more info see `when()`.
1374
+ *
1375
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
1376
+ * and returns true if the url matches the current definition.
1377
+ * @returns {requestHandler} Returns an object with `respond` method that controls how a matched
1378
+ * request is handled. You can save this object for later use and invoke `respond` again in
1379
+ * order to change how a matched request is handled.
1380
+ */
1381
+ createShortMethods('when');
1382
+
1383
+
1384
+ /**
1385
+ * @ngdoc method
1386
+ * @name $httpBackend#expect
1387
+ * @description
1388
+ * Creates a new request expectation.
1389
+ *
1390
+ * @param {string} method HTTP method.
1391
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
1392
+ * and returns true if the url matches the current definition.
1393
+ * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that
1394
+ * receives data string and returns true if the data is as expected, or Object if request body
1395
+ * is in JSON format.
1396
+ * @param {(Object|function(Object))=} headers HTTP headers or function that receives http header
1397
+ * object and returns true if the headers match the current expectation.
1398
+ * @returns {requestHandler} Returns an object with `respond` method that controls how a matched
1399
+ * request is handled. You can save this object for later use and invoke `respond` again in
1400
+ * order to change how a matched request is handled.
1401
+ *
1402
+ * - respond –
1403
+ * `{function([status,] data[, headers, statusText])
1404
+ * | function(function(method, url, data, headers)}`
1405
+ * – The respond method takes a set of static data to be returned or a function that can
1406
+ * return an array containing response status (number), response data (string), response
1407
+ * headers (Object), and the text for the status (string). The respond method returns the
1408
+ * `requestHandler` object for possible overrides.
1409
+ */
1410
+ $httpBackend.expect = function(method, url, data, headers) {
1411
+ var expectation = new MockHttpExpectation(method, url, data, headers),
1412
+ chain = {
1413
+ respond: function(status, data, headers, statusText) {
1414
+ expectation.response = createResponse(status, data, headers, statusText);
1415
+ return chain;
1416
+ }
1417
+ };
1418
+
1419
+ expectations.push(expectation);
1420
+ return chain;
1421
+ };
1422
+
1423
+
1424
+ /**
1425
+ * @ngdoc method
1426
+ * @name $httpBackend#expectGET
1427
+ * @description
1428
+ * Creates a new request expectation for GET requests. For more info see `expect()`.
1429
+ *
1430
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
1431
+ * and returns true if the url matches the current definition.
1432
+ * @param {Object=} headers HTTP headers.
1433
+ * @returns {requestHandler} Returns an object with `respond` method that controls how a matched
1434
+ * request is handled. You can save this object for later use and invoke `respond` again in
1435
+ * order to change how a matched request is handled. See #expect for more info.
1436
+ */
1437
+
1438
+ /**
1439
+ * @ngdoc method
1440
+ * @name $httpBackend#expectHEAD
1441
+ * @description
1442
+ * Creates a new request expectation for HEAD requests. For more info see `expect()`.
1443
+ *
1444
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
1445
+ * and returns true if the url matches the current definition.
1446
+ * @param {Object=} headers HTTP headers.
1447
+ * @returns {requestHandler} Returns an object with `respond` method that controls how a matched
1448
+ * request is handled. You can save this object for later use and invoke `respond` again in
1449
+ * order to change how a matched request is handled.
1450
+ */
1451
+
1452
+ /**
1453
+ * @ngdoc method
1454
+ * @name $httpBackend#expectDELETE
1455
+ * @description
1456
+ * Creates a new request expectation for DELETE requests. For more info see `expect()`.
1457
+ *
1458
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
1459
+ * and returns true if the url matches the current definition.
1460
+ * @param {Object=} headers HTTP headers.
1461
+ * @returns {requestHandler} Returns an object with `respond` method that controls how a matched
1462
+ * request is handled. You can save this object for later use and invoke `respond` again in
1463
+ * order to change how a matched request is handled.
1464
+ */
1465
+
1466
+ /**
1467
+ * @ngdoc method
1468
+ * @name $httpBackend#expectPOST
1469
+ * @description
1470
+ * Creates a new request expectation for POST requests. For more info see `expect()`.
1471
+ *
1472
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
1473
+ * and returns true if the url matches the current definition.
1474
+ * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that
1475
+ * receives data string and returns true if the data is as expected, or Object if request body
1476
+ * is in JSON format.
1477
+ * @param {Object=} headers HTTP headers.
1478
+ * @returns {requestHandler} Returns an object with `respond` method that controls how a matched
1479
+ * request is handled. You can save this object for later use and invoke `respond` again in
1480
+ * order to change how a matched request is handled.
1481
+ */
1482
+
1483
+ /**
1484
+ * @ngdoc method
1485
+ * @name $httpBackend#expectPUT
1486
+ * @description
1487
+ * Creates a new request expectation for PUT requests. For more info see `expect()`.
1488
+ *
1489
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
1490
+ * and returns true if the url matches the current definition.
1491
+ * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that
1492
+ * receives data string and returns true if the data is as expected, or Object if request body
1493
+ * is in JSON format.
1494
+ * @param {Object=} headers HTTP headers.
1495
+ * @returns {requestHandler} Returns an object with `respond` method that controls how a matched
1496
+ * request is handled. You can save this object for later use and invoke `respond` again in
1497
+ * order to change how a matched request is handled.
1498
+ */
1499
+
1500
+ /**
1501
+ * @ngdoc method
1502
+ * @name $httpBackend#expectPATCH
1503
+ * @description
1504
+ * Creates a new request expectation for PATCH requests. For more info see `expect()`.
1505
+ *
1506
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
1507
+ * and returns true if the url matches the current definition.
1508
+ * @param {(string|RegExp|function(string)|Object)=} data HTTP request body or function that
1509
+ * receives data string and returns true if the data is as expected, or Object if request body
1510
+ * is in JSON format.
1511
+ * @param {Object=} headers HTTP headers.
1512
+ * @returns {requestHandler} Returns an object with `respond` method that controls how a matched
1513
+ * request is handled. You can save this object for later use and invoke `respond` again in
1514
+ * order to change how a matched request is handled.
1515
+ */
1516
+
1517
+ /**
1518
+ * @ngdoc method
1519
+ * @name $httpBackend#expectJSONP
1520
+ * @description
1521
+ * Creates a new request expectation for JSONP requests. For more info see `expect()`.
1522
+ *
1523
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives an url
1524
+ * and returns true if the url matches the current definition.
1525
+ * @returns {requestHandler} Returns an object with `respond` method that controls how a matched
1526
+ * request is handled. You can save this object for later use and invoke `respond` again in
1527
+ * order to change how a matched request is handled.
1528
+ */
1529
+ createShortMethods('expect');
1530
+
1531
+
1532
+ /**
1533
+ * @ngdoc method
1534
+ * @name $httpBackend#flush
1535
+ * @description
1536
+ * Flushes all pending requests using the trained responses.
1537
+ *
1538
+ * @param {number=} count Number of responses to flush (in the order they arrived). If undefined,
1539
+ * all pending requests will be flushed. If there are no pending requests when the flush method
1540
+ * is called an exception is thrown (as this typically a sign of programming error).
1541
+ */
1542
+ $httpBackend.flush = function(count, digest) {
1543
+ if (digest !== false) $rootScope.$digest();
1544
+ if (!responses.length) throw new Error('No pending request to flush !');
1545
+
1546
+ if (angular.isDefined(count) && count !== null) {
1547
+ while (count--) {
1548
+ if (!responses.length) throw new Error('No more pending request to flush !');
1549
+ responses.shift()();
1550
+ }
1551
+ } else {
1552
+ while (responses.length) {
1553
+ responses.shift()();
1554
+ }
1555
+ }
1556
+ $httpBackend.verifyNoOutstandingExpectation(digest);
1557
+ };
1558
+
1559
+
1560
+ /**
1561
+ * @ngdoc method
1562
+ * @name $httpBackend#verifyNoOutstandingExpectation
1563
+ * @description
1564
+ * Verifies that all of the requests defined via the `expect` api were made. If any of the
1565
+ * requests were not made, verifyNoOutstandingExpectation throws an exception.
1566
+ *
1567
+ * Typically, you would call this method following each test case that asserts requests using an
1568
+ * "afterEach" clause.
1569
+ *
1570
+ * ```js
1571
+ * afterEach($httpBackend.verifyNoOutstandingExpectation);
1572
+ * ```
1573
+ */
1574
+ $httpBackend.verifyNoOutstandingExpectation = function(digest) {
1575
+ if (digest !== false) $rootScope.$digest();
1576
+ if (expectations.length) {
1577
+ throw new Error('Unsatisfied requests: ' + expectations.join(', '));
1578
+ }
1579
+ };
1580
+
1581
+
1582
+ /**
1583
+ * @ngdoc method
1584
+ * @name $httpBackend#verifyNoOutstandingRequest
1585
+ * @description
1586
+ * Verifies that there are no outstanding requests that need to be flushed.
1587
+ *
1588
+ * Typically, you would call this method following each test case that asserts requests using an
1589
+ * "afterEach" clause.
1590
+ *
1591
+ * ```js
1592
+ * afterEach($httpBackend.verifyNoOutstandingRequest);
1593
+ * ```
1594
+ */
1595
+ $httpBackend.verifyNoOutstandingRequest = function() {
1596
+ if (responses.length) {
1597
+ throw new Error('Unflushed requests: ' + responses.length);
1598
+ }
1599
+ };
1600
+
1601
+
1602
+ /**
1603
+ * @ngdoc method
1604
+ * @name $httpBackend#resetExpectations
1605
+ * @description
1606
+ * Resets all request expectations, but preserves all backend definitions. Typically, you would
1607
+ * call resetExpectations during a multiple-phase test when you want to reuse the same instance of
1608
+ * $httpBackend mock.
1609
+ */
1610
+ $httpBackend.resetExpectations = function() {
1611
+ expectations.length = 0;
1612
+ responses.length = 0;
1613
+ };
1614
+
1615
+ return $httpBackend;
1616
+
1617
+
1618
+ function createShortMethods(prefix) {
1619
+ angular.forEach(['GET', 'DELETE', 'JSONP', 'HEAD'], function(method) {
1620
+ $httpBackend[prefix + method] = function(url, headers) {
1621
+ return $httpBackend[prefix](method, url, undefined, headers);
1622
+ };
1623
+ });
1624
+
1625
+ angular.forEach(['PUT', 'POST', 'PATCH'], function(method) {
1626
+ $httpBackend[prefix + method] = function(url, data, headers) {
1627
+ return $httpBackend[prefix](method, url, data, headers);
1628
+ };
1629
+ });
1630
+ }
1631
+ }
1632
+
1633
+ function MockHttpExpectation(method, url, data, headers) {
1634
+
1635
+ this.data = data;
1636
+ this.headers = headers;
1637
+
1638
+ this.match = function(m, u, d, h) {
1639
+ if (method != m) return false;
1640
+ if (!this.matchUrl(u)) return false;
1641
+ if (angular.isDefined(d) && !this.matchData(d)) return false;
1642
+ if (angular.isDefined(h) && !this.matchHeaders(h)) return false;
1643
+ return true;
1644
+ };
1645
+
1646
+ this.matchUrl = function(u) {
1647
+ if (!url) return true;
1648
+ if (angular.isFunction(url.test)) return url.test(u);
1649
+ if (angular.isFunction(url)) return url(u);
1650
+ return url == u;
1651
+ };
1652
+
1653
+ this.matchHeaders = function(h) {
1654
+ if (angular.isUndefined(headers)) return true;
1655
+ if (angular.isFunction(headers)) return headers(h);
1656
+ return angular.equals(headers, h);
1657
+ };
1658
+
1659
+ this.matchData = function(d) {
1660
+ if (angular.isUndefined(data)) return true;
1661
+ if (data && angular.isFunction(data.test)) return data.test(d);
1662
+ if (data && angular.isFunction(data)) return data(d);
1663
+ if (data && !angular.isString(data)) {
1664
+ return angular.equals(angular.fromJson(angular.toJson(data)), angular.fromJson(d));
1665
+ }
1666
+ return data == d;
1667
+ };
1668
+
1669
+ this.toString = function() {
1670
+ return method + ' ' + url;
1671
+ };
1672
+ }
1673
+
1674
+ function createMockXhr() {
1675
+ return new MockXhr();
1676
+ }
1677
+
1678
+ function MockXhr() {
1679
+
1680
+ // hack for testing $http, $httpBackend
1681
+ MockXhr.$$lastInstance = this;
1682
+
1683
+ this.open = function(method, url, async) {
1684
+ this.$$method = method;
1685
+ this.$$url = url;
1686
+ this.$$async = async;
1687
+ this.$$reqHeaders = {};
1688
+ this.$$respHeaders = {};
1689
+ };
1690
+
1691
+ this.send = function(data) {
1692
+ this.$$data = data;
1693
+ };
1694
+
1695
+ this.setRequestHeader = function(key, value) {
1696
+ this.$$reqHeaders[key] = value;
1697
+ };
1698
+
1699
+ this.getResponseHeader = function(name) {
1700
+ // the lookup must be case insensitive,
1701
+ // that's why we try two quick lookups first and full scan last
1702
+ var header = this.$$respHeaders[name];
1703
+ if (header) return header;
1704
+
1705
+ name = angular.lowercase(name);
1706
+ header = this.$$respHeaders[name];
1707
+ if (header) return header;
1708
+
1709
+ header = undefined;
1710
+ angular.forEach(this.$$respHeaders, function(headerVal, headerName) {
1711
+ if (!header && angular.lowercase(headerName) == name) header = headerVal;
1712
+ });
1713
+ return header;
1714
+ };
1715
+
1716
+ this.getAllResponseHeaders = function() {
1717
+ var lines = [];
1718
+
1719
+ angular.forEach(this.$$respHeaders, function(value, key) {
1720
+ lines.push(key + ': ' + value);
1721
+ });
1722
+ return lines.join('\n');
1723
+ };
1724
+
1725
+ this.abort = angular.noop;
1726
+ }
1727
+
1728
+
1729
+ /**
1730
+ * @ngdoc service
1731
+ * @name $timeout
1732
+ * @description
1733
+ *
1734
+ * This service is just a simple decorator for {@link ng.$timeout $timeout} service
1735
+ * that adds a "flush" and "verifyNoPendingTasks" methods.
1736
+ */
1737
+
1738
+ angular.mock.$TimeoutDecorator = ['$delegate', '$browser', function($delegate, $browser) {
1739
+
1740
+ /**
1741
+ * @ngdoc method
1742
+ * @name $timeout#flush
1743
+ * @description
1744
+ *
1745
+ * Flushes the queue of pending tasks.
1746
+ *
1747
+ * @param {number=} delay maximum timeout amount to flush up until
1748
+ */
1749
+ $delegate.flush = function(delay) {
1750
+ $browser.defer.flush(delay);
1751
+ };
1752
+
1753
+ /**
1754
+ * @ngdoc method
1755
+ * @name $timeout#verifyNoPendingTasks
1756
+ * @description
1757
+ *
1758
+ * Verifies that there are no pending tasks that need to be flushed.
1759
+ */
1760
+ $delegate.verifyNoPendingTasks = function() {
1761
+ if ($browser.deferredFns.length) {
1762
+ throw new Error('Deferred tasks to flush (' + $browser.deferredFns.length + '): ' +
1763
+ formatPendingTasksAsString($browser.deferredFns));
1764
+ }
1765
+ };
1766
+
1767
+ function formatPendingTasksAsString(tasks) {
1768
+ var result = [];
1769
+ angular.forEach(tasks, function(task) {
1770
+ result.push('{id: ' + task.id + ', ' + 'time: ' + task.time + '}');
1771
+ });
1772
+
1773
+ return result.join(', ');
1774
+ }
1775
+
1776
+ return $delegate;
1777
+ }];
1778
+
1779
+ angular.mock.$RAFDecorator = ['$delegate', function($delegate) {
1780
+ var rafFn = function(fn) {
1781
+ var index = rafFn.queue.length;
1782
+ rafFn.queue.push(fn);
1783
+ return function() {
1784
+ rafFn.queue.splice(index, 1);
1785
+ };
1786
+ };
1787
+
1788
+ rafFn.queue = [];
1789
+ rafFn.supported = $delegate.supported;
1790
+
1791
+ rafFn.flush = function() {
1792
+ if (rafFn.queue.length === 0) {
1793
+ throw new Error('No rAF callbacks present');
1794
+ }
1795
+
1796
+ var length = rafFn.queue.length;
1797
+ for (var i = 0; i < length; i++) {
1798
+ rafFn.queue[i]();
1799
+ }
1800
+
1801
+ rafFn.queue = rafFn.queue.slice(i);
1802
+ };
1803
+
1804
+ return rafFn;
1805
+ }];
1806
+
1807
+ /**
1808
+ *
1809
+ */
1810
+ angular.mock.$RootElementProvider = function() {
1811
+ this.$get = function() {
1812
+ return angular.element('<div ng-app></div>');
1813
+ };
1814
+ };
1815
+
1816
+ /**
1817
+ * @ngdoc service
1818
+ * @name $controller
1819
+ * @description
1820
+ * A decorator for {@link ng.$controller} with additional `bindings` parameter, useful when testing
1821
+ * controllers of directives that use {@link $compile#-bindtocontroller- `bindToController`}.
1822
+ *
1823
+ *
1824
+ * ## Example
1825
+ *
1826
+ * ```js
1827
+ *
1828
+ * // Directive definition ...
1829
+ *
1830
+ * myMod.directive('myDirective', {
1831
+ * controller: 'MyDirectiveController',
1832
+ * bindToController: {
1833
+ * name: '@'
1834
+ * }
1835
+ * });
1836
+ *
1837
+ *
1838
+ * // Controller definition ...
1839
+ *
1840
+ * myMod.controller('MyDirectiveController', ['log', function($log) {
1841
+ * $log.info(this.name);
1842
+ * })];
1843
+ *
1844
+ *
1845
+ * // In a test ...
1846
+ *
1847
+ * describe('myDirectiveController', function() {
1848
+ * it('should write the bound name to the log', inject(function($controller, $log) {
1849
+ * var ctrl = $controller('MyDirectiveController', { /* no locals &#42;/ }, { name: 'Clark Kent' });
1850
+ * expect(ctrl.name).toEqual('Clark Kent');
1851
+ * expect($log.info.logs).toEqual(['Clark Kent']);
1852
+ * });
1853
+ * });
1854
+ *
1855
+ * ```
1856
+ *
1857
+ * @param {Function|string} constructor If called with a function then it's considered to be the
1858
+ * controller constructor function. Otherwise it's considered to be a string which is used
1859
+ * to retrieve the controller constructor using the following steps:
1860
+ *
1861
+ * * check if a controller with given name is registered via `$controllerProvider`
1862
+ * * check if evaluating the string on the current scope returns a constructor
1863
+ * * if $controllerProvider#allowGlobals, check `window[constructor]` on the global
1864
+ * `window` object (not recommended)
1865
+ *
1866
+ * The string can use the `controller as property` syntax, where the controller instance is published
1867
+ * as the specified property on the `scope`; the `scope` must be injected into `locals` param for this
1868
+ * to work correctly.
1869
+ *
1870
+ * @param {Object} locals Injection locals for Controller.
1871
+ * @param {Object=} bindings Properties to add to the controller before invoking the constructor. This is used
1872
+ * to simulate the `bindToController` feature and simplify certain kinds of tests.
1873
+ * @return {Object} Instance of given controller.
1874
+ */
1875
+ angular.mock.$ControllerDecorator = ['$delegate', function($delegate) {
1876
+ return function(expression, locals, later, ident) {
1877
+ if (later && typeof later === 'object') {
1878
+ var create = $delegate(expression, locals, true, ident);
1879
+ angular.extend(create.instance, later);
1880
+ return create();
1881
+ }
1882
+ return $delegate(expression, locals, later, ident);
1883
+ };
1884
+ }];
1885
+
1886
+
1887
+ /**
1888
+ * @ngdoc module
1889
+ * @name ngMock
1890
+ * @packageName angular-mocks
1891
+ * @description
1892
+ *
1893
+ * # ngMock
1894
+ *
1895
+ * The `ngMock` module provides support to inject and mock Angular services into unit tests.
1896
+ * In addition, ngMock also extends various core ng services such that they can be
1897
+ * inspected and controlled in a synchronous manner within test code.
1898
+ *
1899
+ *
1900
+ * <div doc-module-components="ngMock"></div>
1901
+ *
1902
+ */
1903
+ angular.module('ngMock', ['ng']).provider({
1904
+ $browser: angular.mock.$BrowserProvider,
1905
+ $exceptionHandler: angular.mock.$ExceptionHandlerProvider,
1906
+ $log: angular.mock.$LogProvider,
1907
+ $interval: angular.mock.$IntervalProvider,
1908
+ $httpBackend: angular.mock.$HttpBackendProvider,
1909
+ $rootElement: angular.mock.$RootElementProvider
1910
+ }).config(['$provide', function($provide) {
1911
+ $provide.decorator('$timeout', angular.mock.$TimeoutDecorator);
1912
+ $provide.decorator('$$rAF', angular.mock.$RAFDecorator);
1913
+ $provide.decorator('$rootScope', angular.mock.$RootScopeDecorator);
1914
+ $provide.decorator('$controller', angular.mock.$ControllerDecorator);
1915
+ }]);
1916
+
1917
+ /**
1918
+ * @ngdoc module
1919
+ * @name ngMockE2E
1920
+ * @module ngMockE2E
1921
+ * @packageName angular-mocks
1922
+ * @description
1923
+ *
1924
+ * The `ngMockE2E` is an angular module which contains mocks suitable for end-to-end testing.
1925
+ * Currently there is only one mock present in this module -
1926
+ * the {@link ngMockE2E.$httpBackend e2e $httpBackend} mock.
1927
+ */
1928
+ angular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) {
1929
+ $provide.decorator('$httpBackend', angular.mock.e2e.$httpBackendDecorator);
1930
+ }]);
1931
+
1932
+ /**
1933
+ * @ngdoc service
1934
+ * @name $httpBackend
1935
+ * @module ngMockE2E
1936
+ * @description
1937
+ * Fake HTTP backend implementation suitable for end-to-end testing or backend-less development of
1938
+ * applications that use the {@link ng.$http $http service}.
1939
+ *
1940
+ * *Note*: For fake http backend implementation suitable for unit testing please see
1941
+ * {@link ngMock.$httpBackend unit-testing $httpBackend mock}.
1942
+ *
1943
+ * This implementation can be used to respond with static or dynamic responses via the `when` api
1944
+ * and its shortcuts (`whenGET`, `whenPOST`, etc) and optionally pass through requests to the
1945
+ * real $httpBackend for specific requests (e.g. to interact with certain remote apis or to fetch
1946
+ * templates from a webserver).
1947
+ *
1948
+ * As opposed to unit-testing, in an end-to-end testing scenario or in scenario when an application
1949
+ * is being developed with the real backend api replaced with a mock, it is often desirable for
1950
+ * certain category of requests to bypass the mock and issue a real http request (e.g. to fetch
1951
+ * templates or static files from the webserver). To configure the backend with this behavior
1952
+ * use the `passThrough` request handler of `when` instead of `respond`.
1953
+ *
1954
+ * Additionally, we don't want to manually have to flush mocked out requests like we do during unit
1955
+ * testing. For this reason the e2e $httpBackend flushes mocked out requests
1956
+ * automatically, closely simulating the behavior of the XMLHttpRequest object.
1957
+ *
1958
+ * To setup the application to run with this http backend, you have to create a module that depends
1959
+ * on the `ngMockE2E` and your application modules and defines the fake backend:
1960
+ *
1961
+ * ```js
1962
+ * myAppDev = angular.module('myAppDev', ['myApp', 'ngMockE2E']);
1963
+ * myAppDev.run(function($httpBackend) {
1964
+ * phones = [{name: 'phone1'}, {name: 'phone2'}];
1965
+ *
1966
+ * // returns the current list of phones
1967
+ * $httpBackend.whenGET('/phones').respond(phones);
1968
+ *
1969
+ * // adds a new phone to the phones array
1970
+ * $httpBackend.whenPOST('/phones').respond(function(method, url, data) {
1971
+ * var phone = angular.fromJson(data);
1972
+ * phones.push(phone);
1973
+ * return [200, phone, {}];
1974
+ * });
1975
+ * $httpBackend.whenGET(/^\/templates\//).passThrough();
1976
+ * //...
1977
+ * });
1978
+ * ```
1979
+ *
1980
+ * Afterwards, bootstrap your app with this new module.
1981
+ */
1982
+
1983
+ /**
1984
+ * @ngdoc method
1985
+ * @name $httpBackend#when
1986
+ * @module ngMockE2E
1987
+ * @description
1988
+ * Creates a new backend definition.
1989
+ *
1990
+ * @param {string} method HTTP method.
1991
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
1992
+ * and returns true if the url matches the current definition.
1993
+ * @param {(string|RegExp)=} data HTTP request body.
1994
+ * @param {(Object|function(Object))=} headers HTTP headers or function that receives http header
1995
+ * object and returns true if the headers match the current definition.
1996
+ * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
1997
+ * control how a matched request is handled. You can save this object for later use and invoke
1998
+ * `respond` or `passThrough` again in order to change how a matched request is handled.
1999
+ *
2000
+ * - respond –
2001
+ * `{function([status,] data[, headers, statusText])
2002
+ * | function(function(method, url, data, headers)}`
2003
+ * – The respond method takes a set of static data to be returned or a function that can return
2004
+ * an array containing response status (number), response data (string), response headers
2005
+ * (Object), and the text for the status (string).
2006
+ * - passThrough – `{function()}` – Any request matching a backend definition with
2007
+ * `passThrough` handler will be passed through to the real backend (an XHR request will be made
2008
+ * to the server.)
2009
+ * - Both methods return the `requestHandler` object for possible overrides.
2010
+ */
2011
+
2012
+ /**
2013
+ * @ngdoc method
2014
+ * @name $httpBackend#whenGET
2015
+ * @module ngMockE2E
2016
+ * @description
2017
+ * Creates a new backend definition for GET requests. For more info see `when()`.
2018
+ *
2019
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
2020
+ * and returns true if the url matches the current definition.
2021
+ * @param {(Object|function(Object))=} headers HTTP headers.
2022
+ * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
2023
+ * control how a matched request is handled. You can save this object for later use and invoke
2024
+ * `respond` or `passThrough` again in order to change how a matched request is handled.
2025
+ */
2026
+
2027
+ /**
2028
+ * @ngdoc method
2029
+ * @name $httpBackend#whenHEAD
2030
+ * @module ngMockE2E
2031
+ * @description
2032
+ * Creates a new backend definition for HEAD requests. For more info see `when()`.
2033
+ *
2034
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
2035
+ * and returns true if the url matches the current definition.
2036
+ * @param {(Object|function(Object))=} headers HTTP headers.
2037
+ * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
2038
+ * control how a matched request is handled. You can save this object for later use and invoke
2039
+ * `respond` or `passThrough` again in order to change how a matched request is handled.
2040
+ */
2041
+
2042
+ /**
2043
+ * @ngdoc method
2044
+ * @name $httpBackend#whenDELETE
2045
+ * @module ngMockE2E
2046
+ * @description
2047
+ * Creates a new backend definition for DELETE requests. For more info see `when()`.
2048
+ *
2049
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
2050
+ * and returns true if the url matches the current definition.
2051
+ * @param {(Object|function(Object))=} headers HTTP headers.
2052
+ * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
2053
+ * control how a matched request is handled. You can save this object for later use and invoke
2054
+ * `respond` or `passThrough` again in order to change how a matched request is handled.
2055
+ */
2056
+
2057
+ /**
2058
+ * @ngdoc method
2059
+ * @name $httpBackend#whenPOST
2060
+ * @module ngMockE2E
2061
+ * @description
2062
+ * Creates a new backend definition for POST requests. For more info see `when()`.
2063
+ *
2064
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
2065
+ * and returns true if the url matches the current definition.
2066
+ * @param {(string|RegExp)=} data HTTP request body.
2067
+ * @param {(Object|function(Object))=} headers HTTP headers.
2068
+ * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
2069
+ * control how a matched request is handled. You can save this object for later use and invoke
2070
+ * `respond` or `passThrough` again in order to change how a matched request is handled.
2071
+ */
2072
+
2073
+ /**
2074
+ * @ngdoc method
2075
+ * @name $httpBackend#whenPUT
2076
+ * @module ngMockE2E
2077
+ * @description
2078
+ * Creates a new backend definition for PUT requests. For more info see `when()`.
2079
+ *
2080
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
2081
+ * and returns true if the url matches the current definition.
2082
+ * @param {(string|RegExp)=} data HTTP request body.
2083
+ * @param {(Object|function(Object))=} headers HTTP headers.
2084
+ * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
2085
+ * control how a matched request is handled. You can save this object for later use and invoke
2086
+ * `respond` or `passThrough` again in order to change how a matched request is handled.
2087
+ */
2088
+
2089
+ /**
2090
+ * @ngdoc method
2091
+ * @name $httpBackend#whenPATCH
2092
+ * @module ngMockE2E
2093
+ * @description
2094
+ * Creates a new backend definition for PATCH requests. For more info see `when()`.
2095
+ *
2096
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
2097
+ * and returns true if the url matches the current definition.
2098
+ * @param {(string|RegExp)=} data HTTP request body.
2099
+ * @param {(Object|function(Object))=} headers HTTP headers.
2100
+ * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
2101
+ * control how a matched request is handled. You can save this object for later use and invoke
2102
+ * `respond` or `passThrough` again in order to change how a matched request is handled.
2103
+ */
2104
+
2105
+ /**
2106
+ * @ngdoc method
2107
+ * @name $httpBackend#whenJSONP
2108
+ * @module ngMockE2E
2109
+ * @description
2110
+ * Creates a new backend definition for JSONP requests. For more info see `when()`.
2111
+ *
2112
+ * @param {string|RegExp|function(string)} url HTTP url or function that receives a url
2113
+ * and returns true if the url matches the current definition.
2114
+ * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
2115
+ * control how a matched request is handled. You can save this object for later use and invoke
2116
+ * `respond` or `passThrough` again in order to change how a matched request is handled.
2117
+ */
2118
+ angular.mock.e2e = {};
2119
+ angular.mock.e2e.$httpBackendDecorator =
2120
+ ['$rootScope', '$timeout', '$delegate', '$browser', createHttpBackendMock];
2121
+
2122
+
2123
+ /**
2124
+ * @ngdoc type
2125
+ * @name $rootScope.Scope
2126
+ * @module ngMock
2127
+ * @description
2128
+ * {@link ng.$rootScope.Scope Scope} type decorated with helper methods useful for testing. These
2129
+ * methods are automatically available on any {@link ng.$rootScope.Scope Scope} instance when
2130
+ * `ngMock` module is loaded.
2131
+ *
2132
+ * In addition to all the regular `Scope` methods, the following helper methods are available:
2133
+ */
2134
+ angular.mock.$RootScopeDecorator = ['$delegate', function($delegate) {
2135
+
2136
+ var $rootScopePrototype = Object.getPrototypeOf($delegate);
2137
+
2138
+ $rootScopePrototype.$countChildScopes = countChildScopes;
2139
+ $rootScopePrototype.$countWatchers = countWatchers;
2140
+
2141
+ return $delegate;
2142
+
2143
+ // ------------------------------------------------------------------------------------------ //
2144
+
2145
+ /**
2146
+ * @ngdoc method
2147
+ * @name $rootScope.Scope#$countChildScopes
2148
+ * @module ngMock
2149
+ * @description
2150
+ * Counts all the direct and indirect child scopes of the current scope.
2151
+ *
2152
+ * The current scope is excluded from the count. The count includes all isolate child scopes.
2153
+ *
2154
+ * @returns {number} Total number of child scopes.
2155
+ */
2156
+ function countChildScopes() {
2157
+ // jshint validthis: true
2158
+ var count = 0; // exclude the current scope
2159
+ var pendingChildHeads = [this.$$childHead];
2160
+ var currentScope;
2161
+
2162
+ while (pendingChildHeads.length) {
2163
+ currentScope = pendingChildHeads.shift();
2164
+
2165
+ while (currentScope) {
2166
+ count += 1;
2167
+ pendingChildHeads.push(currentScope.$$childHead);
2168
+ currentScope = currentScope.$$nextSibling;
2169
+ }
2170
+ }
2171
+
2172
+ return count;
2173
+ }
2174
+
2175
+
2176
+ /**
2177
+ * @ngdoc method
2178
+ * @name $rootScope.Scope#$countWatchers
2179
+ * @module ngMock
2180
+ * @description
2181
+ * Counts all the watchers of direct and indirect child scopes of the current scope.
2182
+ *
2183
+ * The watchers of the current scope are included in the count and so are all the watchers of
2184
+ * isolate child scopes.
2185
+ *
2186
+ * @returns {number} Total number of watchers.
2187
+ */
2188
+ function countWatchers() {
2189
+ // jshint validthis: true
2190
+ var count = this.$$watchers ? this.$$watchers.length : 0; // include the current scope
2191
+ var pendingChildHeads = [this.$$childHead];
2192
+ var currentScope;
2193
+
2194
+ while (pendingChildHeads.length) {
2195
+ currentScope = pendingChildHeads.shift();
2196
+
2197
+ while (currentScope) {
2198
+ count += currentScope.$$watchers ? currentScope.$$watchers.length : 0;
2199
+ pendingChildHeads.push(currentScope.$$childHead);
2200
+ currentScope = currentScope.$$nextSibling;
2201
+ }
2202
+ }
2203
+
2204
+ return count;
2205
+ }
2206
+ }];
2207
+
2208
+
2209
+ if (window.jasmine || window.mocha) {
2210
+
2211
+ var currentSpec = null,
2212
+ annotatedFunctions = [],
2213
+ isSpecRunning = function() {
2214
+ return !!currentSpec;
2215
+ };
2216
+
2217
+ angular.mock.$$annotate = angular.injector.$$annotate;
2218
+ angular.injector.$$annotate = function(fn) {
2219
+ if (typeof fn === 'function' && !fn.$inject) {
2220
+ annotatedFunctions.push(fn);
2221
+ }
2222
+ return angular.mock.$$annotate.apply(this, arguments);
2223
+ };
2224
+
2225
+
2226
+ (window.beforeEach || window.setup)(function() {
2227
+ annotatedFunctions = [];
2228
+ currentSpec = this;
2229
+ });
2230
+
2231
+ (window.afterEach || window.teardown)(function() {
2232
+ var injector = currentSpec.$injector;
2233
+
2234
+ annotatedFunctions.forEach(function(fn) {
2235
+ delete fn.$inject;
2236
+ });
2237
+
2238
+ angular.forEach(currentSpec.$modules, function(module) {
2239
+ if (module && module.$$hashKey) {
2240
+ module.$$hashKey = undefined;
2241
+ }
2242
+ });
2243
+
2244
+ currentSpec.$injector = null;
2245
+ currentSpec.$modules = null;
2246
+ currentSpec = null;
2247
+
2248
+ if (injector) {
2249
+ injector.get('$rootElement').off();
2250
+ }
2251
+
2252
+ // clean up jquery's fragment cache
2253
+ angular.forEach(angular.element.fragments, function(val, key) {
2254
+ delete angular.element.fragments[key];
2255
+ });
2256
+
2257
+ MockXhr.$$lastInstance = null;
2258
+
2259
+ angular.forEach(angular.callbacks, function(val, key) {
2260
+ delete angular.callbacks[key];
2261
+ });
2262
+ angular.callbacks.counter = 0;
2263
+ });
2264
+
2265
+ /**
2266
+ * @ngdoc function
2267
+ * @name angular.mock.module
2268
+ * @description
2269
+ *
2270
+ * *NOTE*: This function is also published on window for easy access.<br>
2271
+ * *NOTE*: This function is declared ONLY WHEN running tests with jasmine or mocha
2272
+ *
2273
+ * This function registers a module configuration code. It collects the configuration information
2274
+ * which will be used when the injector is created by {@link angular.mock.inject inject}.
2275
+ *
2276
+ * See {@link angular.mock.inject inject} for usage example
2277
+ *
2278
+ * @param {...(string|Function|Object)} fns any number of modules which are represented as string
2279
+ * aliases or as anonymous module initialization functions. The modules are used to
2280
+ * configure the injector. The 'ng' and 'ngMock' modules are automatically loaded. If an
2281
+ * object literal is passed they will be registered as values in the module, the key being
2282
+ * the module name and the value being what is returned.
2283
+ */
2284
+ window.module = angular.mock.module = function() {
2285
+ var moduleFns = Array.prototype.slice.call(arguments, 0);
2286
+ return isSpecRunning() ? workFn() : workFn;
2287
+ /////////////////////
2288
+ function workFn() {
2289
+ if (currentSpec.$injector) {
2290
+ throw new Error('Injector already created, can not register a module!');
2291
+ } else {
2292
+ var modules = currentSpec.$modules || (currentSpec.$modules = []);
2293
+ angular.forEach(moduleFns, function(module) {
2294
+ if (angular.isObject(module) && !angular.isArray(module)) {
2295
+ modules.push(function($provide) {
2296
+ angular.forEach(module, function(value, key) {
2297
+ $provide.value(key, value);
2298
+ });
2299
+ });
2300
+ } else {
2301
+ modules.push(module);
2302
+ }
2303
+ });
2304
+ }
2305
+ }
2306
+ };
2307
+
2308
+ /**
2309
+ * @ngdoc function
2310
+ * @name angular.mock.inject
2311
+ * @description
2312
+ *
2313
+ * *NOTE*: This function is also published on window for easy access.<br>
2314
+ * *NOTE*: This function is declared ONLY WHEN running tests with jasmine or mocha
2315
+ *
2316
+ * The inject function wraps a function into an injectable function. The inject() creates new
2317
+ * instance of {@link auto.$injector $injector} per test, which is then used for
2318
+ * resolving references.
2319
+ *
2320
+ *
2321
+ * ## Resolving References (Underscore Wrapping)
2322
+ * Often, we would like to inject a reference once, in a `beforeEach()` block and reuse this
2323
+ * in multiple `it()` clauses. To be able to do this we must assign the reference to a variable
2324
+ * that is declared in the scope of the `describe()` block. Since we would, most likely, want
2325
+ * the variable to have the same name of the reference we have a problem, since the parameter
2326
+ * to the `inject()` function would hide the outer variable.
2327
+ *
2328
+ * To help with this, the injected parameters can, optionally, be enclosed with underscores.
2329
+ * These are ignored by the injector when the reference name is resolved.
2330
+ *
2331
+ * For example, the parameter `_myService_` would be resolved as the reference `myService`.
2332
+ * Since it is available in the function body as _myService_, we can then assign it to a variable
2333
+ * defined in an outer scope.
2334
+ *
2335
+ * ```
2336
+ * // Defined out reference variable outside
2337
+ * var myService;
2338
+ *
2339
+ * // Wrap the parameter in underscores
2340
+ * beforeEach( inject( function(_myService_){
2341
+ * myService = _myService_;
2342
+ * }));
2343
+ *
2344
+ * // Use myService in a series of tests.
2345
+ * it('makes use of myService', function() {
2346
+ * myService.doStuff();
2347
+ * });
2348
+ *
2349
+ * ```
2350
+ *
2351
+ * See also {@link angular.mock.module angular.mock.module}
2352
+ *
2353
+ * ## Example
2354
+ * Example of what a typical jasmine tests looks like with the inject method.
2355
+ * ```js
2356
+ *
2357
+ * angular.module('myApplicationModule', [])
2358
+ * .value('mode', 'app')
2359
+ * .value('version', 'v1.0.1');
2360
+ *
2361
+ *
2362
+ * describe('MyApp', function() {
2363
+ *
2364
+ * // You need to load modules that you want to test,
2365
+ * // it loads only the "ng" module by default.
2366
+ * beforeEach(module('myApplicationModule'));
2367
+ *
2368
+ *
2369
+ * // inject() is used to inject arguments of all given functions
2370
+ * it('should provide a version', inject(function(mode, version) {
2371
+ * expect(version).toEqual('v1.0.1');
2372
+ * expect(mode).toEqual('app');
2373
+ * }));
2374
+ *
2375
+ *
2376
+ * // The inject and module method can also be used inside of the it or beforeEach
2377
+ * it('should override a version and test the new version is injected', function() {
2378
+ * // module() takes functions or strings (module aliases)
2379
+ * module(function($provide) {
2380
+ * $provide.value('version', 'overridden'); // override version here
2381
+ * });
2382
+ *
2383
+ * inject(function(version) {
2384
+ * expect(version).toEqual('overridden');
2385
+ * });
2386
+ * });
2387
+ * });
2388
+ *
2389
+ * ```
2390
+ *
2391
+ * @param {...Function} fns any number of functions which will be injected using the injector.
2392
+ */
2393
+
2394
+
2395
+
2396
+ var ErrorAddingDeclarationLocationStack = function(e, errorForStack) {
2397
+ this.message = e.message;
2398
+ this.name = e.name;
2399
+ if (e.line) this.line = e.line;
2400
+ if (e.sourceId) this.sourceId = e.sourceId;
2401
+ if (e.stack && errorForStack)
2402
+ this.stack = e.stack + '\n' + errorForStack.stack;
2403
+ if (e.stackArray) this.stackArray = e.stackArray;
2404
+ };
2405
+ ErrorAddingDeclarationLocationStack.prototype.toString = Error.prototype.toString;
2406
+
2407
+ window.inject = angular.mock.inject = function() {
2408
+ var blockFns = Array.prototype.slice.call(arguments, 0);
2409
+ var errorForStack = new Error('Declaration Location');
2410
+ return isSpecRunning() ? workFn.call(currentSpec) : workFn;
2411
+ /////////////////////
2412
+ function workFn() {
2413
+ var modules = currentSpec.$modules || [];
2414
+ var strictDi = !!currentSpec.$injectorStrict;
2415
+ modules.unshift('ngMock');
2416
+ modules.unshift('ng');
2417
+ var injector = currentSpec.$injector;
2418
+ if (!injector) {
2419
+ if (strictDi) {
2420
+ // If strictDi is enabled, annotate the providerInjector blocks
2421
+ angular.forEach(modules, function(moduleFn) {
2422
+ if (typeof moduleFn === "function") {
2423
+ angular.injector.$$annotate(moduleFn);
2424
+ }
2425
+ });
2426
+ }
2427
+ injector = currentSpec.$injector = angular.injector(modules, strictDi);
2428
+ currentSpec.$injectorStrict = strictDi;
2429
+ }
2430
+ for (var i = 0, ii = blockFns.length; i < ii; i++) {
2431
+ if (currentSpec.$injectorStrict) {
2432
+ // If the injector is strict / strictDi, and the spec wants to inject using automatic
2433
+ // annotation, then annotate the function here.
2434
+ injector.annotate(blockFns[i]);
2435
+ }
2436
+ try {
2437
+ /* jshint -W040 *//* Jasmine explicitly provides a `this` object when calling functions */
2438
+ injector.invoke(blockFns[i] || angular.noop, this);
2439
+ /* jshint +W040 */
2440
+ } catch (e) {
2441
+ if (e.stack && errorForStack) {
2442
+ throw new ErrorAddingDeclarationLocationStack(e, errorForStack);
2443
+ }
2444
+ throw e;
2445
+ } finally {
2446
+ errorForStack = null;
2447
+ }
2448
+ }
2449
+ }
2450
+ };
2451
+
2452
+
2453
+ angular.mock.inject.strictDi = function(value) {
2454
+ value = arguments.length ? !!value : true;
2455
+ return isSpecRunning() ? workFn() : workFn;
2456
+
2457
+ function workFn() {
2458
+ if (value !== currentSpec.$injectorStrict) {
2459
+ if (currentSpec.$injector) {
2460
+ throw new Error('Injector already created, can not modify strict annotations');
2461
+ } else {
2462
+ currentSpec.$injectorStrict = value;
2463
+ }
2464
+ }
2465
+ }
2466
+ };
2467
+ }
2468
+
2469
+
2470
+ })(window, window.angular);