CommandInterceptorSpec.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575
  1. import {
  2. bootstrapDiagram,
  3. inject
  4. } from 'test/TestHelper';
  5. import inherits from 'inherits';
  6. import cmdModule from 'lib/command';
  7. import CommandInterceptor from 'lib/command/CommandInterceptor';
  8. // example commands
  9. function TracableCommand() {
  10. this.execute = function(ctx) { };
  11. this.revert = function(ctx) { };
  12. }
  13. function SimpleCommand() {
  14. TracableCommand.call(this);
  15. }
  16. function ComplexCommand(commandStack) {
  17. TracableCommand.call(this);
  18. this.preExecute = function(ctx) {
  19. commandStack.execute('pre-command', { element: ctx.element });
  20. };
  21. this.postExecute = function(ctx) {
  22. commandStack.execute('post-command', { element: ctx.element });
  23. };
  24. }
  25. function PreCommand() {
  26. TracableCommand.call(this);
  27. }
  28. function PostCommand() {
  29. TracableCommand.call(this);
  30. }
  31. /**
  32. * A command interceptor used for testing
  33. */
  34. function TestInterceptor(eventBus) {
  35. CommandInterceptor.call(this, eventBus);
  36. }
  37. TestInterceptor.$inject = [ 'eventBus' ];
  38. inherits(TestInterceptor, CommandInterceptor);
  39. describe('command/CommandInterceptor', function() {
  40. beforeEach(bootstrapDiagram({ modules: [ cmdModule ] }));
  41. var element, context;
  42. beforeEach(inject(function(commandStack) {
  43. element = { trace: [] };
  44. context = {
  45. element: element
  46. };
  47. commandStack.registerHandler('simple-command', SimpleCommand);
  48. commandStack.registerHandler('complex-command', ComplexCommand);
  49. commandStack.registerHandler('pre-command', PreCommand);
  50. commandStack.registerHandler('post-command', PostCommand);
  51. }));
  52. function traceCommand(e) {
  53. expect(e).to.exist;
  54. e.context.element.trace.push(e.command);
  55. }
  56. function traceUnwrappedCommand(context, command, event) {
  57. expect(context).to.exist;
  58. expect(command).to.exist;
  59. expect(event).to.exist;
  60. context.element.trace.push(command);
  61. }
  62. describe('should hook into commands', function() {
  63. describe('#preExecute', function() {
  64. it('should register global', inject(function(commandStack, eventBus) {
  65. var interceptor = new TestInterceptor(eventBus);
  66. interceptor.preExecute(traceCommand);
  67. // when
  68. commandStack.execute('simple-command', context);
  69. commandStack.execute('pre-command', context);
  70. // then
  71. expect(element.trace).to.eql([
  72. 'simple-command',
  73. 'pre-command'
  74. ]);
  75. }));
  76. it('should register global / unwrap', inject(function(commandStack, eventBus) {
  77. var interceptor = new TestInterceptor(eventBus);
  78. interceptor.preExecute(traceUnwrappedCommand, true);
  79. // when
  80. commandStack.execute('simple-command', context);
  81. commandStack.execute('pre-command', context);
  82. // then
  83. expect(element.trace).to.eql([
  84. 'simple-command',
  85. 'pre-command'
  86. ]);
  87. }));
  88. it('should register scoped', inject(function(commandStack, eventBus) {
  89. var interceptor = new TestInterceptor(eventBus);
  90. interceptor.preExecute('simple-command', traceCommand);
  91. // when
  92. commandStack.execute('simple-command', context);
  93. commandStack.execute('pre-command', context);
  94. // then
  95. expect(element.trace).to.eql([
  96. 'simple-command'
  97. ]);
  98. }));
  99. it('should register scoped / unwrap', inject(function(commandStack, eventBus) {
  100. var interceptor = new TestInterceptor(eventBus);
  101. interceptor.preExecute('simple-command', traceUnwrappedCommand, true);
  102. // when
  103. commandStack.execute('simple-command', context);
  104. commandStack.execute('pre-command', context);
  105. // then
  106. expect(element.trace).to.eql([
  107. 'simple-command'
  108. ]);
  109. }));
  110. });
  111. describe('#preExecuted', function() {
  112. it('should register scoped', inject(function(commandStack, eventBus) {
  113. var interceptor = new TestInterceptor(eventBus);
  114. interceptor.preExecuted('simple-command', traceCommand);
  115. // when
  116. commandStack.execute('simple-command', context);
  117. commandStack.execute('pre-command', context);
  118. // then
  119. expect(element.trace).to.eql([
  120. 'simple-command'
  121. ]);
  122. }));
  123. });
  124. describe('#postExecute', function() {
  125. it('should register scoped', inject(function(commandStack, eventBus) {
  126. var interceptor = new TestInterceptor(eventBus);
  127. interceptor.postExecute('simple-command', traceCommand);
  128. // when
  129. commandStack.execute('simple-command', context);
  130. commandStack.execute('pre-command', context);
  131. // then
  132. expect(element.trace).to.eql([
  133. 'simple-command'
  134. ]);
  135. }));
  136. });
  137. describe('#postExecuted', function() {
  138. it('should register scoped', inject(function(commandStack, eventBus) {
  139. var interceptor = new TestInterceptor(eventBus);
  140. interceptor.postExecuted('simple-command', traceCommand);
  141. // when
  142. commandStack.execute('simple-command', context);
  143. commandStack.execute('pre-command', context);
  144. // then
  145. expect(element.trace).to.eql([
  146. 'simple-command'
  147. ]);
  148. }));
  149. });
  150. describe('#canExecute', function() {
  151. it('should register scoped', inject(function(commandStack, eventBus) {
  152. var interceptor = new TestInterceptor(eventBus);
  153. interceptor.canExecute('simple-command', traceCommand);
  154. // when
  155. commandStack.canExecute('simple-command', context);
  156. commandStack.canExecute('pre-command', context);
  157. // then
  158. expect(element.trace).to.eql([
  159. 'simple-command'
  160. ]);
  161. }));
  162. });
  163. describe('#execute', function() {
  164. it('should register scoped', inject(function(commandStack, eventBus) {
  165. var interceptor = new TestInterceptor(eventBus);
  166. interceptor.execute('simple-command', traceCommand);
  167. // when
  168. commandStack.execute('simple-command', context);
  169. commandStack.execute('pre-command', context);
  170. // then
  171. expect(element.trace).to.eql([
  172. 'simple-command'
  173. ]);
  174. }));
  175. });
  176. describe('#executed', function() {
  177. it('should register scoped', inject(function(commandStack, eventBus) {
  178. var interceptor = new TestInterceptor(eventBus);
  179. interceptor.executed('simple-command', traceCommand);
  180. // when
  181. commandStack.execute('simple-command', context);
  182. commandStack.execute('pre-command', context);
  183. // then
  184. expect(element.trace).to.eql([
  185. 'simple-command'
  186. ]);
  187. }));
  188. });
  189. describe('#revert', function() {
  190. it('should register scoped', inject(function(commandStack, eventBus) {
  191. var interceptor = new TestInterceptor(eventBus);
  192. interceptor.executed('simple-command', traceCommand);
  193. // when
  194. commandStack.execute('simple-command', context);
  195. commandStack.execute('pre-command', context);
  196. commandStack.undo();
  197. commandStack.undo();
  198. // then
  199. expect(element.trace).to.eql([
  200. 'simple-command'
  201. ]);
  202. }));
  203. });
  204. describe('#reverted', function() {
  205. it('should register scoped', inject(function(commandStack, eventBus) {
  206. var interceptor = new TestInterceptor(eventBus);
  207. interceptor.executed('simple-command', traceCommand);
  208. // when
  209. commandStack.execute('simple-command', context);
  210. commandStack.execute('pre-command', context);
  211. commandStack.undo();
  212. commandStack.undo();
  213. // then
  214. expect(element.trace).to.eql([
  215. 'simple-command'
  216. ]);
  217. }));
  218. });
  219. describe('#on', function() {
  220. it('should register global preExecute', inject(function(commandStack, eventBus) {
  221. var interceptor = new TestInterceptor(eventBus);
  222. interceptor.on('preExecute', traceCommand);
  223. // when
  224. commandStack.execute('simple-command', context);
  225. // then
  226. expect(element.trace).to.eql([
  227. 'simple-command'
  228. ]);
  229. }));
  230. it('should register global preExecute / unwrap', inject(function(commandStack, eventBus) {
  231. var interceptor = new TestInterceptor(eventBus);
  232. interceptor.on('preExecute', traceUnwrappedCommand, true);
  233. // when
  234. commandStack.execute('simple-command', context);
  235. // then
  236. expect(element.trace).to.eql([
  237. 'simple-command'
  238. ]);
  239. }));
  240. });
  241. });
  242. describe('priorities', function() {
  243. function trace(suffix) {
  244. return function(e) {
  245. e.context.element.trace.push(e.command + '-' + suffix);
  246. };
  247. }
  248. describe('via #preExecute', function() {
  249. it('should register globally', inject(function(commandStack, eventBus) {
  250. var interceptor = new TestInterceptor(eventBus);
  251. interceptor.preExecute(500, trace('low'));
  252. interceptor.preExecute(trace('default'));
  253. interceptor.preExecute(1600, trace('high'));
  254. // when
  255. commandStack.execute('simple-command', context);
  256. // then
  257. expect(element.trace).to.eql([
  258. 'simple-command-high',
  259. 'simple-command-default',
  260. 'simple-command-low'
  261. ]);
  262. }));
  263. it('should register locally', inject(function(commandStack, eventBus) {
  264. var interceptor = new TestInterceptor(eventBus);
  265. interceptor.preExecute('simple-command', 500, trace('low'));
  266. interceptor.preExecute('simple-command', trace('default'));
  267. interceptor.preExecute('simple-command', 1600, trace('high'));
  268. // when
  269. commandStack.execute('simple-command', context);
  270. // then
  271. expect(element.trace).to.eql([
  272. 'simple-command-high',
  273. 'simple-command-default',
  274. 'simple-command-low'
  275. ]);
  276. }));
  277. });
  278. describe('via #on', function() {
  279. it('should register', inject(function(commandStack, eventBus) {
  280. var interceptor = new TestInterceptor(eventBus);
  281. interceptor.on('preExecute', 500, trace('global-low'));
  282. interceptor.on([ 'simple-command.preExecute' ], trace('local-default'));
  283. interceptor.on('simple-command', 'preExecute', 1600, trace('local-high'));
  284. // when
  285. commandStack.execute('simple-command', context);
  286. // then
  287. expect(element.trace).to.eql([
  288. 'simple-command-local-high',
  289. 'simple-command-local-default',
  290. 'simple-command-global-low'
  291. ]);
  292. }));
  293. });
  294. describe('mixed', function() {
  295. it('should register mixed', inject(function(commandStack, eventBus) {
  296. var interceptor = new TestInterceptor(eventBus);
  297. interceptor.on([ 'simple-command.preExecute', 'preExecute'], 500, trace('raw-multiple-low'));
  298. interceptor.preExecute([ 'simple-command' ], 500, trace('local-multiple-low'));
  299. interceptor.preExecute(500, trace('global-low'));
  300. interceptor.preExecute('simple-command', trace('default'));
  301. interceptor.preExecute(1500, trace('global-high'));
  302. interceptor.preExecute('simple-command', 1600, trace('local-high'));
  303. // when
  304. commandStack.execute('simple-command', context);
  305. // then
  306. expect(element.trace).to.eql([
  307. // local listeners are invoked first
  308. 'simple-command-local-high',
  309. 'simple-command-default',
  310. 'simple-command-raw-multiple-low',
  311. 'simple-command-local-multiple-low',
  312. // global listeners are invoked after local ones
  313. 'simple-command-global-high',
  314. 'simple-command-raw-multiple-low',
  315. 'simple-command-global-low'
  316. ]);
  317. }));
  318. });
  319. });
  320. describe('context', function() {
  321. function Dog() {
  322. this.barks = [];
  323. }
  324. Dog.prototype.bark = function() {
  325. this.barks.push('WOOF WOOF');
  326. };
  327. beforeEach(inject(function(commandStack) {
  328. commandStack.registerHandler('bark', ComplexCommand);
  329. }));
  330. it('should pass context -> WITHOUT unwrap', inject(function(commandStack, eventBus) {
  331. var interceptor = new TestInterceptor(eventBus);
  332. // given
  333. Dog.prototype.bindListener = function() {
  334. interceptor.execute('bark', function(event) {
  335. return this.bark();
  336. }, this);
  337. };
  338. var bobby = new Dog();
  339. bobby.bindListener();
  340. // when
  341. commandStack.execute('bark', context);
  342. // then
  343. expect(bobby.barks).to.have.length(1);
  344. }));
  345. it('should pass context -> WITH unwrap', inject(function(commandStack, eventBus) {
  346. var interceptor = new TestInterceptor(eventBus);
  347. // given
  348. Dog.prototype.bindListener = function() {
  349. interceptor.execute('bark', function(event) {
  350. return this.bark();
  351. }, true, this);
  352. };
  353. var bobby = new Dog();
  354. bobby.bindListener();
  355. // when
  356. commandStack.execute('bark', context);
  357. // then
  358. expect(bobby.barks).to.have.length(1);
  359. }));
  360. it('should pass context -> WITH everything', inject(function(commandStack, eventBus) {
  361. var interceptor = new TestInterceptor(eventBus);
  362. // given
  363. Dog.prototype.bindListener = function() {
  364. interceptor.execute('bark', 1000, function(event) {
  365. return this.bark();
  366. }, false, this);
  367. };
  368. var bobby = new Dog();
  369. bobby.bindListener();
  370. // when
  371. commandStack.execute('bark', context);
  372. // then
  373. expect(bobby.barks).to.have.length(1);
  374. }));
  375. });
  376. });