action_sequence_test.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. var App = require('app');
  19. require('utils/action_sequence');
  20. describe('App.actionSequence', function () {
  21. var actionSequence;
  22. beforeEach(function () {
  23. actionSequence = App.actionSequence.create();
  24. });
  25. describe('#setSequence', function () {
  26. var cases = [
  27. {
  28. sequenceIn: [{}, {}],
  29. sequenceOut: [{}, {}],
  30. title: 'array passed'
  31. },
  32. {
  33. sequenceIn: {
  34. '0': {},
  35. '1': {},
  36. 'length': 2
  37. },
  38. sequenceOut: [{}],
  39. title: 'array-like object passed'
  40. },
  41. {
  42. sequenceIn: 0,
  43. sequenceOut: [{}],
  44. title: 'primitive passed'
  45. }
  46. ],
  47. result;
  48. cases.forEach(function (item) {
  49. describe(item.title, function () {
  50. beforeEach(function () {
  51. actionSequence.set('sequence', [{}]);
  52. result = actionSequence.setSequence(item.sequenceIn);
  53. });
  54. it('should return context', function () {
  55. expect(result).to.eql(actionSequence);
  56. });
  57. it('sequence property', function () {
  58. expect(actionSequence.get('sequence')).to.eql(item.sequenceOut);
  59. });
  60. });
  61. });
  62. });
  63. describe('#start', function () {
  64. beforeEach(function () {
  65. actionSequence.setProperties({
  66. actionCounter: 0,
  67. sequence: [{}]
  68. });
  69. sinon.stub(actionSequence, 'runNextAction', Em.K);
  70. actionSequence.start();
  71. });
  72. afterEach(function () {
  73. actionSequence.runNextAction.restore();
  74. });
  75. it('should set the counter', function () {
  76. expect(actionSequence.get('actionCounter')).to.equal(1);
  77. });
  78. it('should start the sequence', function () {
  79. expect(actionSequence.runNextAction.calledOnce).to.be.true;
  80. });
  81. it('should call runNextAction with correct arguments', function () {
  82. expect(actionSequence.runNextAction.calledWith(0, null)).to.be.true;
  83. });
  84. });
  85. describe('#onFinish', function () {
  86. var cases = [
  87. {
  88. callbackIn: Em.isNone,
  89. callbackOut: Em.isNone,
  90. title: 'function passed'
  91. },
  92. {
  93. callbackIn: 'function () {}',
  94. callbackOut: Em.clb,
  95. title: 'array-like object passed'
  96. },
  97. {
  98. callbackIn: 'function () {}',
  99. callbackOut: Em.clb,
  100. title: 'primitive passed'
  101. }
  102. ],
  103. result;
  104. cases.forEach(function (item) {
  105. describe(item.title, function () {
  106. beforeEach(function () {
  107. actionSequence.set('finishedCallback', Em.clb);
  108. result = actionSequence.onFinish(item.callbackIn);
  109. });
  110. it('should return context', function () {
  111. expect(result).to.eql(actionSequence);
  112. });
  113. it('finishedCallback property', function () {
  114. expect(actionSequence.get('finishedCallback')).to.eql(item.callbackOut);
  115. });
  116. });
  117. });
  118. });
  119. describe('#runNextAction', function () {
  120. var actions = {
  121. callback: Em.K,
  122. sync: function (prevResponse) {
  123. actions.callback(prevResponse);
  124. return prevResponse;
  125. },
  126. async: function (prevResponse) {
  127. actions.callback(prevResponse);
  128. return {
  129. done: function (callback) {
  130. return callback.call(this, prevResponse);
  131. }
  132. };
  133. }
  134. },
  135. prevResponse = {},
  136. cases = [
  137. {
  138. index: 0,
  139. actionCounter: 0,
  140. sequence: [
  141. {
  142. callback: actions.sync,
  143. type: 'sync'
  144. }
  145. ],
  146. actionCallCount: 0,
  147. title: 'no iterations left (case 1)'
  148. },
  149. {
  150. index: 3,
  151. actionCounter: 3,
  152. sequence: [
  153. {
  154. callback: actions.sync,
  155. type: 'sync'
  156. },
  157. {
  158. callback: actions.sync,
  159. type: 'sync'
  160. },
  161. {
  162. callback: actions.sync,
  163. type: 'sync'
  164. }
  165. ],
  166. actionCallCount: 0,
  167. title: 'no iterations left (case 2)'
  168. },
  169. {
  170. index: 1,
  171. actionCounter: 3,
  172. sequence: [
  173. {
  174. callback: actions.sync,
  175. type: 'sync'
  176. },
  177. {
  178. callback: actions.sync,
  179. type: 'sync'
  180. },
  181. {
  182. callback: actions.sync,
  183. type: 'sync'
  184. }
  185. ],
  186. actionCallCount: 2,
  187. title: 'starting from the middle'
  188. },
  189. {
  190. index: 0,
  191. actionCounter: 2,
  192. sequence: [
  193. {
  194. callback: actions.sync,
  195. type: 'sync'
  196. },
  197. {
  198. callback: actions.sync,
  199. type: 'sync'
  200. },
  201. {
  202. callback: actions.sync,
  203. type: 'sync'
  204. }
  205. ],
  206. actionCallCount: 2,
  207. title: 'ending at the middle'
  208. },
  209. {
  210. index: 0,
  211. actionCounter: 3,
  212. sequence: [
  213. {
  214. callback: actions.sync,
  215. type: 'sync'
  216. },
  217. {
  218. callback: actions.sync,
  219. type: 'sync'
  220. },
  221. {
  222. callback: actions.sync,
  223. type: 'sync'
  224. }
  225. ],
  226. actionCallCount: 3,
  227. title: 'all iterations'
  228. },
  229. {
  230. index: 0,
  231. actionCounter: 3,
  232. sequence: [
  233. {
  234. callback: actions.sync,
  235. type: 'sync'
  236. },
  237. {
  238. callback: actions.async,
  239. type: 'async'
  240. },
  241. {
  242. callback: actions.sync,
  243. type: 'sync'
  244. }
  245. ],
  246. actionCallCount: 3,
  247. title: 'asynchronous action'
  248. }
  249. ];
  250. cases.forEach(function (item) {
  251. describe(item.title, function () {
  252. beforeEach(function () {
  253. sinon.spy(actions, 'callback');
  254. sinon.stub(actionSequence, 'finishedCallback', Em.K);
  255. actionSequence.setProperties({
  256. context: actionSequence,
  257. actionCounter: item.actionCounter,
  258. sequence: item.sequence
  259. });
  260. actionSequence.runNextAction(item.index, prevResponse);
  261. });
  262. afterEach(function () {
  263. actions.callback.restore();
  264. actionSequence.finishedCallback.restore();
  265. });
  266. it('number of calls', function () {
  267. expect(actions.callback.callCount).to.equal(item.actionCallCount);
  268. });
  269. if (item.actionCallCount) {
  270. it('argument passed to callback', function () {
  271. expect(actions.callback.alwaysCalledWith(prevResponse)).to.be.true;
  272. });
  273. }
  274. it('finish callback', function () {
  275. expect(actionSequence.finishedCallback.calledOnce).to.be.true;
  276. });
  277. });
  278. });
  279. });
  280. });