exit-rttc.test.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  1. /**
  2. * Module dependencies
  3. */
  4. var util = require('util');
  5. var _ = require('@sailshq/lodash');
  6. var assert = require('assert');
  7. var Machine = require('../');
  8. var runSuite = require('../node_modules/rttc/spec/helpers/run-suite');
  9. var TEST_SUITE = require('../node_modules/rttc/spec/coercion.spec.js');
  10. var toRunTest = require('./util/test-exit-coercion.helper');
  11. var expandSuite = require('../node_modules/rttc/spec/helpers/expand-suite');
  12. describe('output coercion (for exits)', function (){
  13. describe('using exhaustive fixtures from RTTC', function (){
  14. // Take the array of tests and extend them with some derivative
  15. // tests automatically. Then run them.
  16. runSuite(expandSuite(TEST_SUITE), toRunTest );
  17. });//</using exhaustive fixtures from RTTC>
  18. describe('additional test cases specific to the machine runner', function() {
  19. it('should pass through expected data', function(done) {
  20. Machine.build({
  21. inputs: {
  22. foo: {
  23. example: 'foo bar'
  24. }
  25. },
  26. exits: {
  27. success: {
  28. example: 'hello'
  29. },
  30. error: {
  31. example: 'world'
  32. }
  33. },
  34. fn: function (inputs, exits, deps) {
  35. exits(null, 'foo');
  36. }
  37. })
  38. .configure({
  39. foo: 'hello'
  40. })
  41. .exec(function(err, result) {
  42. if(err) { return done(err); }
  43. assert(result === 'foo');
  44. done();
  45. });
  46. });
  47. it('should coerce invalid exit data into the correct types', function(done) {
  48. Machine.build({
  49. inputs: {
  50. foo: {
  51. example: 'foo bar'
  52. }
  53. },
  54. exits: {
  55. success: {
  56. example: 4
  57. },
  58. error: {
  59. example: 'world'
  60. }
  61. },
  62. fn: function (inputs, exits, deps) {
  63. exits(null, '100');
  64. }
  65. })
  66. .configure({
  67. foo: 'hello'
  68. })
  69. .exec(function(err, result) {
  70. if(err) { return done(err); }
  71. assert.strictEqual(result,100);
  72. done();
  73. });
  74. });
  75. it('should provide base types for values not present in the exit data', function(done) {
  76. Machine.build({
  77. inputs: {
  78. foo: {
  79. example: 'foo bar'
  80. }
  81. },
  82. exits: {
  83. success: {
  84. example: 4
  85. },
  86. error: {
  87. example: 'world'
  88. }
  89. },
  90. fn: function (inputs, exits, deps) {
  91. exits(null);
  92. }
  93. })
  94. .configure({
  95. foo: 'hello'
  96. })
  97. .exec(function(err, result) {
  98. if(err) { return done(err); }
  99. assert.strictEqual(result,0);
  100. done();
  101. });
  102. });
  103. it('should coerce string to number', function(done) {
  104. Machine.build({
  105. inputs: {},
  106. exits: {
  107. success: {
  108. example: 4
  109. }
  110. },
  111. fn: function (inputs, exits, deps) {
  112. exits.success('whatever');
  113. }
  114. }).exec(function(err, result) {
  115. if(err) { return done(err); }
  116. assert.strictEqual(result,0);
  117. done();
  118. });
  119. });
  120. it('should coerce boolean to number', function(done) {
  121. Machine.build({
  122. inputs: {},
  123. exits: {
  124. success: {
  125. example: 4
  126. }
  127. },
  128. fn: function (inputs, exits, deps) {
  129. exits.success(true);
  130. }
  131. }).exec(function(err, result) {
  132. if(err) { return done(err); }
  133. assert.strictEqual(result,1);
  134. done();
  135. });
  136. });
  137. it('should coerce undefined to example ({})', function(done) {
  138. Machine.build({
  139. inputs: {},
  140. exits: {
  141. success: {
  142. example: {}
  143. }
  144. },
  145. fn: function (inputs, exits, deps) {
  146. exits.success();
  147. }
  148. }).exec(function(err, result) {
  149. if(err) { return done(err); }
  150. assert.deepEqual(result,{});
  151. done();
  152. });
  153. });
  154. it('should coerce 0 to example ({})', function(done) {
  155. Machine.build({
  156. inputs: {},
  157. exits: {
  158. success: {
  159. example: {}
  160. }
  161. },
  162. fn: function (inputs, exits, deps) {
  163. exits.success(0);
  164. }
  165. }).exec(function(err, result) {
  166. if(err) { return done(err); }
  167. assert.deepEqual(result,{});
  168. done();
  169. });
  170. });
  171. it('should coerce 0 to example ({foo: ""})', function(done) {
  172. Machine.build({
  173. inputs: {},
  174. exits: {
  175. success: {
  176. example: {foo: 'bar'}
  177. }
  178. },
  179. fn: function (inputs, exits, deps) {
  180. exits.success(0);
  181. }
  182. }).exec(function(err, result) {
  183. if(err) { return done(err); }
  184. assert.deepEqual(result,{foo:''});
  185. done();
  186. });
  187. });
  188. it('should coerce 0 to example ({foo: [""], bar: {}})', function(done) {
  189. Machine.build({
  190. inputs: {},
  191. exits: {
  192. success: {
  193. example: {foo: ['stuff'], bar: {}}
  194. }
  195. },
  196. fn: function (inputs, exits, deps) {
  197. exits.success(0);
  198. }
  199. }).exec(function(err, result) {
  200. if(err) { return done(err); }
  201. assert.deepEqual(result,{foo:[], bar: {}});
  202. done();
  203. });
  204. });
  205. it('should coerce 0 to example ({foo: [""], bar: {baz: 0}})', function(done) {
  206. Machine.build({
  207. inputs: {},
  208. exits: {
  209. success: {
  210. example: {foo: ['stuff'], bar: {baz: 12412}}
  211. }
  212. },
  213. fn: function (inputs, exits, deps) {
  214. exits.success(0);
  215. }
  216. }).exec(function(err, result) {
  217. if(err) { return done(err); }
  218. assert.deepEqual(result,{foo:[], bar: {baz: 0}});
  219. done();
  220. });
  221. });
  222. it('should coerce 0 to example ({foo: [""], someArray: []})', function(done) {
  223. Machine.build({
  224. inputs: {},
  225. exits: {
  226. success: {
  227. example: {foo: ['stuff'], someArray: []}
  228. }
  229. },
  230. fn: function (inputs, exits, deps) {
  231. exits.success(0);
  232. }
  233. }).exec(function(err, result) {
  234. if(err) { return done(err); }
  235. assert.deepEqual(result,{foo:[], someArray: []});
  236. done();
  237. });
  238. });
  239. it('should coerce 0 to example ({foo: [""], someArray: []}) with someArray in example => ["*"]', function(done) {
  240. Machine.build({
  241. inputs: {},
  242. exits: {
  243. success: {
  244. example: {foo: ['stuff'], someArray: ['*']}
  245. }
  246. },
  247. fn: function (inputs, exits, deps) {
  248. exits.success(0);
  249. }
  250. }).exec(function(err, result) {
  251. if(err) { return done(err); }
  252. assert.deepEqual(result,{foo:[], someArray: []});
  253. done();
  254. });
  255. });
  256. it('should coerce `{foo: ["hi"], someArray: [1234]}` to `{foo: ["hi"], someArray: [1234]}` with someArray in example => ["*"]', function(done) {
  257. Machine.build({
  258. inputs: {},
  259. exits: {
  260. success: {
  261. example: {foo: ['stuff'], someArray: ['*']}
  262. }
  263. },
  264. fn: function (inputs, exits, deps) {
  265. exits.success({foo: ['hi'], someArray: [1234]});
  266. }
  267. }).exec(function(err, result) {
  268. if(err) { return done(err); }
  269. assert.deepEqual(result,{foo:['hi'], someArray: [1234]});
  270. done();
  271. });
  272. });
  273. it('should coerce undefined to example ([])', function(done) {
  274. Machine.build({
  275. inputs: {},
  276. exits: {
  277. success: {
  278. example: []
  279. }
  280. },
  281. fn: function (inputs, exits, deps) {
  282. exits.success();
  283. }
  284. }).exec(function(err, result) {
  285. if(err) { return done(err); }
  286. assert.deepEqual(result,[]);
  287. done();
  288. });
  289. });
  290. it('should coerce null to example ([])', function(done) {
  291. Machine.build({
  292. inputs: {},
  293. exits: {
  294. success: {
  295. example: []
  296. }
  297. },
  298. fn: function (inputs, exits, deps) {
  299. exits.success(null);
  300. }
  301. }).exec(function(err, result) {
  302. if(err) { return done(err); }
  303. assert.deepEqual(result,[]);
  304. done();
  305. });
  306. });
  307. it('should coerce 0 to example ([])', function(done) {
  308. Machine.build({
  309. inputs: {},
  310. exits: {
  311. success: {
  312. example: []
  313. }
  314. },
  315. fn: function (inputs, exits, deps) {
  316. exits.success(0);
  317. }
  318. }).exec(function(err, result) {
  319. if(err) { return done(err); }
  320. assert.deepEqual(result,[]);
  321. done();
  322. });
  323. });
  324. it('should coerce 0 to example ([0])', function(done) {
  325. Machine.build({
  326. inputs: {},
  327. exits: {
  328. success: {
  329. example: [123]
  330. }
  331. },
  332. fn: function (inputs, exits, deps) {
  333. exits.success(0);
  334. }
  335. }).exec(function(err, result) {
  336. if(err) { return done(err); }
  337. assert.deepEqual(result,[]);
  338. done();
  339. });
  340. });
  341. it('should coerce 0 to example ([""])', function(done) {
  342. Machine.build({
  343. inputs: {},
  344. exits: {
  345. success: {
  346. example: ['stuff']
  347. }
  348. },
  349. fn: function (inputs, exits, deps) {
  350. exits.success(0);
  351. }
  352. }).exec(function(err, result) {
  353. if(err) { return done(err); }
  354. assert.deepEqual(result,[]);
  355. done();
  356. });
  357. });
  358. it('should coerce 0 to example ([false])', function(done) {
  359. Machine.build({
  360. inputs: {},
  361. exits: {
  362. success: {
  363. example: [true]
  364. }
  365. },
  366. fn: function (inputs, exits, deps) {
  367. exits.success(0);
  368. }
  369. }).exec(function(err, result) {
  370. if(err) { return done(err); }
  371. assert.deepEqual(result,[]);
  372. done();
  373. });
  374. });
  375. ///////////////////////////////////////////////////////////////////////////////////////////////
  376. // Some edge cases:
  377. ///////////////////////////////////////////////////////////////////////////////////////////////
  378. var edgeCaseMachineDef = {
  379. inputs: {
  380. criteria: {
  381. friendlyName: 'criteria',
  382. typeclass: 'dictionary',
  383. description: 'Waterline search criteria to use in retrieving Job instances'
  384. }
  385. },
  386. exits: {
  387. success: {
  388. friendlyName: 'then',
  389. example: {
  390. title: 'scott',
  391. description: 'scott',
  392. votes: 123,
  393. id: 123
  394. }
  395. },
  396. error: {
  397. example: undefined
  398. },
  399. notFound: {
  400. void: true
  401. }
  402. },
  403. fn: function(inputs, exits, env) {
  404. function Thing(){}
  405. var thing = new Thing();
  406. thing.id=1;
  407. thing.votes=null;
  408. thing.description='stuff';
  409. thing.title='thing';
  410. // return exits(null, thing);
  411. return exits.success(thing);
  412. },
  413. identity: 'findOne_job'
  414. };
  415. // Same as edgeCaseMachine but w/ a slightly different fn that uses switchback-style usage:
  416. var edgeCaseMachineDef2 = _.cloneDeep(edgeCaseMachineDef);
  417. edgeCaseMachineDef2.fn = function(inputs, exits, env) {
  418. function Thing(){}
  419. var thing = new Thing();
  420. thing.id=1;
  421. thing.votes=null;
  422. thing.description='stuff';
  423. thing.title='thing';
  424. return exits(null, thing);
  425. };
  426. it('should coerce output properly (null=>0 in this case) when using normal `exits.success(result)` from within the machine `fn`', function (done){
  427. Machine.build(edgeCaseMachineDef).configure({criteria: {id: 1}}).exec({
  428. error: function (err){
  429. return done(err);
  430. },
  431. success: function (result){
  432. assert.equal(result.votes, 0, 'Expected `votes` property of result to equal zero, but check out the result:'+util.inspect(result));
  433. return done();
  434. }
  435. });
  436. });
  437. it('should coerce output properly (null=>0 in this case) when using implementor switchback (`exits(err, result)`) within the machine `fn`', function (done){
  438. Machine.build(edgeCaseMachineDef2).configure({criteria: {id: 1}}).exec({
  439. error: function (err){
  440. return done(err);
  441. },
  442. success: function (result){
  443. assert.equal(result.votes, 0, 'Expected `votes` property of result to equal zero, but check out the result:'+util.inspect(result));
  444. return done();
  445. }
  446. });
  447. });
  448. it('should reject `null` exit example', function (done){
  449. Machine.build({
  450. inputs: {},
  451. exits: {
  452. success: {
  453. friendlyName: 'then',
  454. example: {
  455. title: 'scott',
  456. description: 'scott',
  457. votes: null,
  458. id: 123
  459. }
  460. }
  461. },
  462. fn: function (inputs, exits) {
  463. exits.success();
  464. }
  465. }).exec({
  466. error: function (err){
  467. return done();
  468. },
  469. success: function (result){
  470. return done(new Error('Expected error exit to be traversed because exit example contains a null value.'));
  471. }
  472. });
  473. });
  474. });//</additional test cases specific to the machine runner>
  475. });