like-and-itemOf.test.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  1. /**
  2. * Module dependencies
  3. */
  4. var assert = require('assert');
  5. var _ = require('@sailshq/lodash');
  6. var Machine = require('../');
  7. var testMachineWithMocha = require('test-machinepack-mocha').testMachineWithMocha;
  8. describe('`like` and `itemOf`', function (){
  9. describe('using `like` in one of its exits', function (){
  10. testMachineWithMocha().machine(Machine.build({
  11. identity: 'test',
  12. inputs: { fullName: { example: 'Roger Rabbit' } },
  13. exits: { success: { like: 'fullName' } },
  14. fn: function (inputs, exits) { return exits.success(123); }
  15. }))
  16. .use({})
  17. .expect({
  18. outcome: 'success',
  19. output: '123'
  20. });
  21. describe('and referenced input is configured with an invalid (and incompatible) input value', function (){
  22. testMachineWithMocha().machine(Machine.build({
  23. identity: 'test',
  24. inputs: { fullName: { example: 'Roger Rabbit' } },
  25. exits: { success: { like: 'fullName' } },
  26. fn: function (inputs, exits) { return exits.success(123); }
  27. }))
  28. .use({ fullName: [] })
  29. .expect({
  30. outcome: 'error'
  31. });
  32. });
  33. it('should not .build() the machine if an input refers to another input w/ a `like` or `itemOf` instead of an example', function (){
  34. assert.throws(function (){
  35. Machine.build({
  36. identity: 'test',
  37. inputs: {
  38. fullName: { example: 'Roger Rabbit' },
  39. firstName: { like: 'fullName' },
  40. },
  41. exits: { success: { like: 'firstName' } },
  42. fn: function (inputs, exits) { return exits.error(); }
  43. });
  44. });
  45. assert.throws(function (){
  46. Machine.build({
  47. identity: 'test',
  48. inputs: {
  49. nameParts: { example: ['Roger'] },
  50. firstName: { itemOf: 'fullName' },
  51. },
  52. exits: { success: { like: 'firstName' } },
  53. fn: function (inputs, exits) { return exits.error(); }
  54. });
  55. });
  56. });
  57. });
  58. // No longer supported:
  59. // describe('using `like` in one of its inputs', function (){
  60. // testMachineWithMocha().machine(Machine.build({
  61. // identity: 'test',
  62. // inputs: {
  63. // fullName: { example: 'Roger Rabbit' },
  64. // firstName: { like: 'fullName' }
  65. // },
  66. // exits: { success: { example: '===' } },
  67. // fn: function (inputs, exits) { return exits.success(inputs.firstName); }
  68. // }))
  69. // .use({ firstName: 123 })
  70. // .expect({
  71. // outcome: 'success',
  72. // output: '123'
  73. // });
  74. // describe('and referenced input is configured with an invalid (and incompatible) input value', function (){
  75. // testMachineWithMocha().machine(Machine.build({
  76. // identity: 'test',
  77. // inputs: {
  78. // fullName: { example: 'Roger Rabbit' },
  79. // firstName: { like: 'fullName' }
  80. // },
  81. // exits: { success: { example: '===' } },
  82. // fn: function (inputs, exits) { return exits.success(inputs.firstName); }
  83. // }))
  84. // .use({ firstName: 123, fullName: [] })
  85. // .expect({
  86. // outcome: 'error'
  87. // });
  88. // });
  89. // it('should not .build() the machine if an input refers to itself', function (){
  90. // assert.throws(function (){
  91. // Machine.build({
  92. // identity: 'test',
  93. // inputs: {
  94. // fullName: { example: 'Roger Rabbit' },
  95. // firstName: { like: 'firstName' }
  96. // },
  97. // exits: { success: { example: '===' } },
  98. // fn: function (inputs, exits) { return exits.error(); }
  99. // });
  100. // });
  101. // });
  102. // it('should not .build() the machine if an input refers to another input w/ a `like` or `itemOf` instead of an example', function (){
  103. // assert.throws(function (){
  104. // Machine.build({
  105. // identity: 'test',
  106. // inputs: {
  107. // fullName: { example: 'Roger Rabbit' },
  108. // lastName: { like: 'firstName' },
  109. // firstName: { like: 'fullName' }
  110. // },
  111. // exits: { success: { example: '===' } },
  112. // fn: function (inputs, exits) { return exits.error(); }
  113. // });
  114. // });
  115. // assert.throws(function (){
  116. // Machine.build({
  117. // identity: 'test',
  118. // inputs: {
  119. // namePieces: { example: ['Roger'] },
  120. // lastName: { itemOf: 'namePieces' },
  121. // firstName: { like: 'lastName' }
  122. // },
  123. // exits: { success: { example: '===' } },
  124. // fn: function (inputs, exits) { return exits.error(); }
  125. // });
  126. // });
  127. // });
  128. // });
  129. describe('using `itemOf` in one of its exits', function (){
  130. testMachineWithMocha().machine(Machine.build({
  131. identity: 'test',
  132. inputs: {
  133. fullName: { example: ['Roger'] }
  134. },
  135. exits: { success: { itemOf: 'fullName' } },
  136. fn: function (inputs, exits) { return exits.success(123); }
  137. }))
  138. .use({})
  139. .expect({
  140. outcome: 'success',
  141. output: '123'
  142. });
  143. });
  144. describe('using `itemOf` in one of its inputs', function (){
  145. it('should no longer work!', function(){
  146. try {
  147. testMachineWithMocha().machine(Machine.build({
  148. identity: 'test',
  149. inputs: {
  150. fullName: { example: ['Roger'] },
  151. firstName: { itemOf: 'fullName' }
  152. },
  153. exits: { success: { example: '===' } },
  154. fn: function (inputs, exits) { return exits.success(inputs.firstName); }
  155. }))
  156. .use({ firstName: 123 })
  157. .expect({
  158. outcome: 'success',
  159. output: '123'
  160. });
  161. } catch (err) {
  162. if (err.name === 'ImplementationError') {
  163. // ok that's what we expected.
  164. }
  165. else { throw err; }
  166. }
  167. throw new Error('should not have made it here');
  168. });
  169. });
  170. describe('using `like` in one of its contract\'s exits', function (){
  171. testMachineWithMocha().machine(Machine.build({
  172. identity: 'test',
  173. inputs: {
  174. fullName: { example: 'Roger' },
  175. getFullName: {
  176. example: '->',
  177. contract: {
  178. sync: true,
  179. exits: { success: { like: 'fullName' } }
  180. }
  181. }
  182. },
  183. exits: { success: { outputExample: '===' } },
  184. fn: function (inputs, exits) { return exits.success( inputs.getFullName().execSync() ); }
  185. }))
  186. .use({
  187. getFullName: function (unused, exits){
  188. exits.success(123);
  189. }
  190. })
  191. .expect({
  192. outcome: 'success',
  193. output: '123'
  194. });
  195. });
  196. describe('using `like` in one of its contract\'s inputs', function (){
  197. testMachineWithMocha().machine(Machine.build({
  198. identity: 'test',
  199. inputs: {
  200. fullName: { example: 'Roger' },
  201. getFullName: {
  202. example: '->',
  203. contract: {
  204. sync: true,
  205. inputs: { name: { like: 'fullName' } },
  206. exits: { success: { example: '===' } }
  207. }
  208. }
  209. },
  210. exits: { success: { example: '===' } },
  211. fn: function (inputs, exits) { return exits.success( inputs.getFullName({ name: 123 }).execSync() ); }
  212. }))
  213. .use({
  214. getFullName: function (inputs, exits){
  215. return exits.success(inputs.name);
  216. }
  217. })
  218. .expect({
  219. outcome: 'success',
  220. output: '123'
  221. });
  222. });
  223. describe('using `itemOf` in one of its contract\'s exits', function (){
  224. testMachineWithMocha().machine(Machine.build({
  225. identity: 'test',
  226. inputs: {
  227. fullName: { example: ['Roger'] },
  228. getFullName: {
  229. example: '->',
  230. contract: {
  231. sync: true,
  232. exits: { success: { itemOf: 'fullName' } }
  233. }
  234. }
  235. },
  236. exits: { success: { example: '===' } },
  237. fn: function (inputs, exits) { return exits.success( inputs.getFullName().execSync() ); }
  238. }))
  239. .use({
  240. getFullName: function (unused, exits){
  241. exits.success(123);
  242. }
  243. })
  244. .expect({
  245. outcome: 'success',
  246. output: '123'
  247. });
  248. });
  249. describe('using `itemOf` in one of its contract\'s inputs', function (){
  250. testMachineWithMocha().machine(Machine.build({
  251. identity: 'test',
  252. inputs: {
  253. fullName: { example: ['Roger'] },
  254. getFullName: {
  255. example: '->',
  256. contract: {
  257. sync: true,
  258. inputs: { name: { itemOf: 'fullName' } },
  259. exits: { success: { example: '===' } }
  260. }
  261. }
  262. },
  263. exits: { success: { example: '===' } },
  264. fn: function (inputs, exits) { return exits.success( inputs.getFullName({ name: 123 }).execSync() ); }
  265. }))
  266. .use({
  267. getFullName: function (inputs, exits){
  268. return exits.success(inputs.name);
  269. }
  270. })
  271. .expect({
  272. outcome: 'success',
  273. output: '123'
  274. });
  275. });
  276. describe('using `like` in one of its contract\'s inputs\' contract\'s exits', function (){
  277. testMachineWithMocha().machine(Machine.build({
  278. identity: 'test',
  279. inputs: {
  280. fullName: { example: 'Roger' },
  281. getFullName: {
  282. example: '->',
  283. contract: {
  284. sync: true,
  285. inputs: {
  286. toCompleteName: {
  287. example: '->',
  288. contract: {
  289. sync: true,
  290. exits: { success: { like: 'fullName' } }
  291. }
  292. }
  293. },
  294. exits: { success: { example: '===' } }
  295. }
  296. }
  297. },
  298. exits: { success: { example: '===' } },
  299. fn: function (inputs, exits) {
  300. return exits.success( inputs.getFullName({
  301. toCompleteName: function (unused, exits){
  302. return exits.success(123);
  303. }
  304. }).execSync() );
  305. }
  306. }))
  307. .use({
  308. getFullName: function (inputs, exits){
  309. return exits.success( inputs.toCompleteName().execSync() );
  310. }
  311. })
  312. .expect({
  313. outcome: 'success',
  314. output: '123'
  315. });
  316. });
  317. describe('using `like` in one of its contract\'s inputs\' contract\'s inputs', function (){
  318. testMachineWithMocha().machine(Machine.build({
  319. identity: 'test',
  320. inputs: {
  321. fullName: { example: 'Roger' },
  322. getFullName: {
  323. example: '->',
  324. contract: {
  325. sync: true,
  326. inputs: {
  327. toCompleteName: {
  328. example: '->',
  329. contract: {
  330. sync: true,
  331. inputs: { name: { like: 'fullName' } },
  332. exits: { success: { example: '===' } }
  333. }
  334. }
  335. },
  336. exits: { success: { example: '===' } }
  337. }
  338. }
  339. },
  340. exits: { success: { example: '===' } },
  341. fn: function (inputs, exits) {
  342. return exits.success( inputs.getFullName({
  343. toCompleteName: function (inputs, exits){
  344. return exits.success(inputs.name);
  345. }
  346. }).execSync() );
  347. }
  348. }))
  349. .use({
  350. getFullName: function (inputs, exits){
  351. return exits.success( inputs.toCompleteName({name:123}).execSync() );
  352. }
  353. })
  354. .expect({
  355. outcome: 'success',
  356. output: '123'
  357. });
  358. });
  359. describe('using `itemOf` in one of its contract\'s inputs\' contract\'s exits', function (){
  360. testMachineWithMocha().machine(Machine.build({
  361. identity: 'test',
  362. inputs: {
  363. fullName: { example: ['Roger'] },
  364. getFullName: {
  365. example: '->',
  366. contract: {
  367. sync: true,
  368. inputs: {
  369. toCompleteName: {
  370. example: '->',
  371. contract: {
  372. sync: true,
  373. exits: { success: { itemOf: 'fullName' } }
  374. }
  375. }
  376. },
  377. exits: { success: { example: '===' } }
  378. }
  379. }
  380. },
  381. exits: { success: { example: '===' } },
  382. fn: function (inputs, exits) {
  383. return exits.success( inputs.getFullName({
  384. toCompleteName: function (unused, exits){
  385. return exits.success(123);
  386. }
  387. }).execSync() );
  388. }
  389. }))
  390. .use({
  391. getFullName: function (inputs, exits){
  392. return exits.success( inputs.toCompleteName().execSync() );
  393. }
  394. })
  395. .expect({
  396. outcome: 'success',
  397. output: '123'
  398. });
  399. });
  400. describe('using `itemOf` in one of its contract\'s inputs\' contract\'s inputs', function (){
  401. testMachineWithMocha().machine(Machine.build({
  402. identity: 'test',
  403. inputs: {
  404. fullName: { example: ['Roger'] },
  405. getFullName: {
  406. example: '->',
  407. contract: {
  408. sync: true,
  409. inputs: {
  410. toCompleteName: {
  411. example: '->',
  412. contract: {
  413. sync: true,
  414. inputs: { name: { itemOf: 'fullName' } },
  415. exits: { success: { example: '===' } }
  416. }
  417. }
  418. },
  419. exits: { success: { example: '===' } }
  420. }
  421. }
  422. },
  423. exits: { success: { example: '===' } },
  424. fn: function (inputs, exits) {
  425. return exits.success( inputs.getFullName({
  426. toCompleteName: function (inputs, exits){
  427. return exits.success(inputs.name);
  428. }
  429. }).execSync() );
  430. }
  431. }))
  432. .use({
  433. getFullName: function (inputs, exits){
  434. return exits.success( inputs.toCompleteName({ name: 123 }).execSync() );
  435. }
  436. })
  437. .expect({
  438. outcome: 'success',
  439. output: '123'
  440. });
  441. });
  442. });