validation.spec.js 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689
  1. // ██████╗ ████████╗████████╗ ██████╗ ███████╗██████╗ ███████╗ ██████╗
  2. // ██╔══██╗╚══██╔══╝╚══██╔══╝██╔════╝ ██╔════╝██╔══██╗██╔════╝██╔════╝ ██╗██╗
  3. // ██████╔╝ ██║ ██║ ██║ ███████╗██████╔╝█████╗ ██║ ╚═╝╚═╝
  4. // ██╔══██╗ ██║ ██║ ██║ ╚════██║██╔═══╝ ██╔══╝ ██║ ██╗██╗
  5. // ██║ ██║ ██║ ██║ ╚██████╗ ███████║██║ ███████╗╚██████╗ ╚═╝╚═╝
  6. // ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚══════╝ ╚═════╝
  7. //
  8. // ██╗ ██╗ █████╗ ██╗ ██╗██████╗ █████╗ ████████╗██╗ ██████╗ ███╗ ██╗
  9. // ██║ ██║██╔══██╗██║ ██║██╔══██╗██╔══██╗╚══██╔══╝██║██╔═══██╗████╗ ██║
  10. // ██║ ██║███████║██║ ██║██║ ██║███████║ ██║ ██║██║ ██║██╔██╗ ██║
  11. // ╚██╗ ██╔╝██╔══██║██║ ██║██║ ██║██╔══██║ ██║ ██║██║ ██║██║╚██╗██║
  12. // ╚████╔╝ ██║ ██║███████╗██║██████╔╝██║ ██║ ██║ ██║╚██████╔╝██║ ╚████║
  13. // ╚═══╝ ╚═╝ ╚═╝╚══════╝╚═╝╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝
  14. //
  15. // Export the array of tests below
  16. module.exports = [
  17. ////////////////////////////////////////////
  18. // STRINGS
  19. ////////////////////////////////////////////
  20. { example: 'foo', actual: 'bar', result: 'bar' },
  21. { example: 'foo', actual: '', result: '' },
  22. { example: 'foo', actual: 0, result: '0' },
  23. { example: 'foo', actual: 1, result: '1' },
  24. { example: 'foo', actual: -1.1, result: '-1.1' },
  25. { example: 'foo', actual: -0, result: '0' },
  26. { example: 'foo', actual: +0, result: '0' },
  27. { example: 'foo', actual: true, result: 'true' },
  28. { example: 'foo', actual: false, result: 'false' },
  29. { example: 'foo', actual: {}, error: true },
  30. { example: 'foo', actual: {foo:'bar'}, error: true },
  31. { example: 'foo', actual: {foo:{bar:{baz:{}}}}, error: true },
  32. { example: 'foo', actual: {foo:['bar']}, error: true },
  33. { example: 'foo', actual: {foo:{bar:{baz:[{}]}}}, error: true },
  34. { example: 'foo', actual: [], error: true },
  35. { example: 'foo', actual: ['asdf'], error: true },
  36. { example: 'foo', actual: [''], error: true },
  37. { example: 'foo', actual: [235], error: true },
  38. { example: 'foo', actual: [false], error: true },
  39. { example: 'foo', actual: [{}], error: true },
  40. { example: 'foo', actual: [{foo:'bar'}], error: true },
  41. { example: 'foo', actual: undefined, error: true },
  42. { example: 'foo', actual: NaN, error: true },
  43. { example: 'foo', actual: Infinity, error: true },
  44. { example: 'foo', actual: -Infinity, error: true },
  45. { example: 'foo', actual: null, error: true },
  46. { example: 'foo', actual: /some regexp/, error: true },
  47. { example: 'foo', actual: function(){}, error: true },
  48. { example: 'foo', actual: new Date('November 5, 1605 GMT'), result: '1605-11-05T00:00:00.000Z' },
  49. { example: 'foo', actual: new (require('stream').Readable)(), error: true },
  50. { example: 'foo', actual: new Buffer('asdf'), error: true },
  51. { example: 'foo', actual: new Error('asdf'), error: true },
  52. ////////////////////////////////////////////
  53. // NUMBERS
  54. ////////////////////////////////////////////
  55. { example: 123, actual: 'bar', error: true },
  56. { example: 123, actual: '', error: true },
  57. { example: 123, actual: '0', result: 0 },
  58. { example: 123, actual: '1', result: 1 },
  59. { example: 123, actual: '-1.1', result: -1.1 },
  60. { example: 123, actual: 'NaN', error: true },
  61. { example: 123, actual: 'undefined', error: true },
  62. { example: 123, actual: 'null', error: true },
  63. { example: 123, actual: '-Infinity', error: true },
  64. { example: 123, actual: 'Infinity', error: true },
  65. { example: 123, actual: 0, result: 0 },
  66. { example: 123, actual: 1, result: 1 },
  67. { example: 123, actual: -1.1, result: -1.1 },
  68. { example: 123, actual: -0, result: 0 },
  69. { example: 123, actual: +0, result: 0 },
  70. { example: 123, actual: true, result: 1 },
  71. { example: 123, actual: false, result: 0 },
  72. { example: 123, actual: {}, error: true },
  73. { example: 123, actual: {foo:'bar'}, error: true },
  74. { example: 123, actual: {foo:{bar:{baz:{}}}}, error: true },
  75. { example: 123, actual: {foo:['bar']}, error: true },
  76. { example: 123, actual: {foo:{bar:{baz:[{}]}}}, error: true },
  77. { example: 123, actual: [], error: true },
  78. { example: 123, actual: ['asdf'], error: true },
  79. { example: 123, actual: [''], error: true },
  80. { example: 123, actual: [235], error: true },
  81. { example: 123, actual: [false], error: true },
  82. { example: 123, actual: [{}], error: true },
  83. { example: 123, actual: [{foo:'bar'}], error: true },
  84. { example: 123, actual: undefined, error: true },
  85. { example: 123, actual: NaN, error: true },
  86. { example: 123, actual: Infinity, error: true },
  87. { example: 123, actual: -Infinity, error: true },
  88. { example: 123, actual: null, error: true },
  89. { example: 123, actual: /some regexp/, error: true },
  90. { example: 123, actual: function(){}, error: true },
  91. { example: 123, actual: new Date('November 5, 1605 GMT'), result: -11491632000000 },
  92. { example: 123, actual: new (require('stream').Readable)(), error: true },
  93. { example: 123, actual: new Buffer('asdf'), error: true },
  94. { example: 123, actual: new Error('asdf'), error: true },
  95. ////////////////////////////////////////////
  96. // BOOLEANS
  97. ////////////////////////////////////////////
  98. { example: true, actual: 'bar', error: true },
  99. { example: true, actual: '', error: true },
  100. { example: true, actual: '-1.1', error: true },
  101. { example: true, actual: 'NaN', error: true },
  102. { example: true, actual: 'undefined', error: true },
  103. { example: true, actual: 'null', error: true },
  104. { example: true, actual: '-Infinity', error: true },
  105. { example: true, actual: 'Infinity', error: true },
  106. { example: true, actual: 'true', result: true },
  107. { example: true, actual: 'false', result: false },
  108. { example: true, actual: '0', result: false },
  109. { example: true, actual: '1', result: true },
  110. { example: true, actual: 0, result: false },
  111. { example: true, actual: 1, result: true },
  112. { example: true, actual: -1.1, error: true },
  113. { example: true, actual: -0, result: false },
  114. { example: true, actual: +0, result: false },
  115. { example: true, actual: true, result: true },
  116. { example: true, actual: false, result: false },
  117. { example: true, actual: {}, error: true },
  118. { example: true, actual: {foo:'bar'}, error: true },
  119. { example: true, actual: {foo:{bar:{baz:{}}}}, error: true },
  120. { example: true, actual: {foo:['bar']}, error: true },
  121. { example: true, actual: {foo:{bar:{baz:[{}]}}}, error: true },
  122. { example: true, actual: [], error: true },
  123. { example: true, actual: ['asdf'], error: true },
  124. { example: true, actual: [''], error: true },
  125. { example: true, actual: [235], error: true },
  126. { example: true, actual: [false], error: true },
  127. { example: true, actual: [{}], error: true },
  128. { example: true, actual: [{foo:'bar'}], error: true },
  129. { example: true, actual: undefined, error: true },
  130. { example: true, actual: NaN, error: true },
  131. { example: true, actual: Infinity, error: true },
  132. { example: true, actual: -Infinity, error: true },
  133. { example: true, actual: null, error: true },
  134. { example: true, actual: /some regexp/, error: true },
  135. { example: true, actual: function(){}, error: true },
  136. { example: true, actual: new Date('November 5, 1605 GMT'), error: true },
  137. { example: true, actual: new (require('stream').Readable)(), error: true },
  138. { example: true, actual: new Buffer('asdf'), error: true },
  139. { example: true, actual: new Error('asdf'), error: true },
  140. ////////////////////////////////////////////
  141. // DICTIONARIES (json-serializable, except `null` not allowed)
  142. ////////////////////////////////////////////
  143. { example: {}, actual: 'bar', error: true },
  144. { example: {}, actual: 123, error: true },
  145. { example: {}, actual: true, error: true },
  146. { example: {}, actual: {}, result: {} },
  147. { example: {}, actual: {foo:'bar'}, result: {foo:'bar'} },
  148. { example: {}, actual: {foo:{bar:{baz:{}}}}, result: {foo:{bar:{baz:{}}}} },
  149. { example: {}, actual: {foo:['bar']}, result: {foo:['bar']} },
  150. { example: {}, actual: {foo:{bar:{baz:[{}]}}}, result: {foo:{bar:{baz:[{}]}}} },
  151. { example: {}, actual: [], error: true },
  152. { example: {}, actual: ['asdf'], error: true },
  153. { example: {}, actual: [''], error: true },
  154. { example: {}, actual: [235], error: true },
  155. { example: {}, actual: [false], error: true },
  156. { example: {}, actual: [{}], error: true },
  157. { example: {}, actual: [{foo:'bar'}], error: true },
  158. { example: {}, actual: undefined, error: true },
  159. { example: {}, actual: NaN, error: true },
  160. { example: {}, actual: Infinity, error: true },
  161. { example: {}, actual: -Infinity, error: true },
  162. { example: {}, actual: null, error: true },
  163. { example: {}, actual: /some regexp/, error: true },
  164. { example: {}, actual: function(){}, error: true },
  165. { example: {}, actual: new Date('November 5, 1605 GMT'), error: true },
  166. // Note that the enumerable properties for Streams vary between Node.js versions.
  167. { example: {}, actual: new (require('stream').Readable)(), error: true },
  168. // Note that the enumerable properties for Buffers vary between Node.js versions.
  169. { example: {}, actual: new Buffer('asdf'), error: true },
  170. { example: {}, actual: new Error('asdf'), error: true },
  171. ////////////////////////////////////////////
  172. // ARRAYS (json-serializable, except `null` not allowed)
  173. // (all of the tests below pass w/ [], not necessarily ['==='])
  174. ////////////////////////////////////////////
  175. { example: [], actual: 'bar', error: true },
  176. { example: [], actual: 123, error: true },
  177. { example: [], actual: true, error: true },
  178. { example: [], actual: {}, error: true },
  179. { example: [], actual: {foo:'bar'}, error: true },
  180. { example: [], actual: {foo:{bar:{baz:{}}}}, error: true },
  181. { example: [], actual: {foo:['bar']}, error: true },
  182. { example: [], actual: {foo:{bar:{baz:[{}]}}}, error: true },
  183. { example: [], actual: [], result: [] },
  184. { example: [], actual: ['asdf'], result: ['asdf'] },
  185. { example: [], actual: [''], result: [''] },
  186. { example: [], actual: [235], result: [235] },
  187. { example: [], actual: [false], result: [false] },
  188. { example: [], actual: [{}], result: [{}] },
  189. { example: [], actual: [{foo:'bar'}], result: [{foo: 'bar'}] },
  190. { example: [], actual: undefined, error: true },
  191. { example: [], actual: NaN, error: true },
  192. { example: [], actual: Infinity, error: true },
  193. { example: [], actual: -Infinity, error: true },
  194. { example: [], actual: null, error: true },
  195. { example: [], actual: /some regexp/, error: true },
  196. { example: [], actual: function(){}, error: true },
  197. { example: [], actual: new Date('November 5, 1605 GMT'), error: true },
  198. { example: [], actual: new (require('stream').Readable)(), error: true }, // TODO: consider enhancing this behavior to concat the stream contents? Needs community discussion.
  199. // Skip Buffer tests for now since the enumerable properties vary between Node.js versions.
  200. // { example: [], actual: new Buffer('asdf'), result: [ 97, 115, 100, 102 ] },
  201. // Note: we could bring back support for this by explicitly filtering properties of buffers in `.exec()`
  202. // TODO: but actually, this should cause an error- use `example: '==='` for things like this.
  203. { example: [], actual: new Error('asdf'), error: true },
  204. //////////////////////////////////////////////////////
  205. // nested contents of `example: []` and `example: {}`
  206. //////////////////////////////////////////////////////
  207. // Follow JSON-serialization rules for nested objects within `example: []` and `example: {}`
  208. // with the following exceptions:
  209. // • convert Error instances to their `.stack` property (a string)
  210. // • convert RegExp instances to a string
  211. // • convert functions to a string
  212. // • after doing the rest of the things, prune undefined/null items
  213. // • after doing the rest of the things, strip keys w/ undefined/null values
  214. { example: {}, actual: { x: undefined }, result: {} },
  215. { example: {}, actual: { x: NaN }, result: {x:0} },
  216. { example: {}, actual: { x: Infinity }, result: {x:0} },
  217. { example: {}, actual: { x: -Infinity }, result: {x:0} },
  218. { example: {}, actual: { x: null }, result: {x: null} },
  219. { example: {}, actual: { x: function foo(a,b){return a+' '+b;} }, result: { x: 'function foo(a,b){return a+\' \'+b;}' } },
  220. // { example: {}, actual: { x: undefined, null, NaN, -Infinity, Infinity, function(){} }, result: [] },
  221. { example: {}, actual: { x: /some regexp/ig }, result: {x:'/some regexp/gi' }},
  222. { example: {}, actual: { x: new Date('November 5, 1605 GMT') }, result: {x: '1605-11-05T00:00:00.000Z'} },
  223. // Skip Readable stream tests for now since the enumerable properties vary between Node.js versions.
  224. // { example: {}, actual: { x: new (require('stream').Readable)() }, result: { x: { _readableState: {},readable: true,_events: {},_maxListeners: 10 } } },
  225. // Skip Buffer stream tests for now since the enumerable properties vary between Node.js versions.
  226. // { example: {}, actual: { x: new Buffer('asdf') } , result: {x: {}} },
  227. (function (){
  228. // Hard-code a fake `.stack` to avoid differences between computers that would cause tests to fail
  229. var e = new Error('asdf');
  230. e.stack = 'fake_error';
  231. return { example: {}, actual: { x: e }, result: {x:'fake_error'} };
  232. })(),
  233. { example: [], actual: [undefined], result: [] },
  234. { example: [], actual: [null], result: [null] },
  235. { example: [], actual: [NaN], result: [0] },
  236. { example: [], actual: [Infinity], result: [0] },
  237. { example: [], actual: [-Infinity], result: [0] },
  238. { example: [], actual: [function foo(a,b){return a+' '+b;}], result: ['function foo(a,b){return a+\' \'+b;}'] },
  239. { example: [], actual: [/some regexp/gi], result: ['/some regexp/gi'] },
  240. { example: [], actual: [new Date('November 5, 1605 GMT')], result: ['1605-11-05T00:00:00.000Z'] },
  241. // Skip Readable stream tests for now since the enumerable properties vary between Node.js versions.
  242. // { example: [], actual: [new (require('stream').Readable)()], result: [ { _readableState: {},readable: true,_events: {},_maxListeners: 10 }] },
  243. // Skip Buffer stream tests for now since the enumerable properties vary between Node.js versions.
  244. // { example: [], actual: [new Buffer('asdf')], result: [{}] },
  245. (function (){
  246. var e = new Error('asdf');
  247. e.stack = 'fake_error';
  248. return { example: [], actual: [e], result: ['fake_error'] };
  249. })(),
  250. ////////////////////////////////////////////
  251. // example: '*' (any JSON-serializable value)
  252. ////////////////////////////////////////////
  253. { example: '*', actual: 'bar', result: 'bar', },
  254. { example: '*', actual: '', result: '', },
  255. { example: '*', actual: '-1.1', result: '-1.1', },
  256. { example: '*', actual: 'NaN', result: 'NaN', },
  257. { example: '*', actual: 'undefined', result: 'undefined', },
  258. { example: '*', actual: 'null', result: 'null', },
  259. { example: '*', actual: '-Infinity', result: '-Infinity', },
  260. { example: '*', actual: 'Infinity', result: 'Infinity', },
  261. { example: '*', actual: 'true', result: 'true', },
  262. { example: '*', actual: 'false', result: 'false', },
  263. { example: '*', actual: '0', result: '0', },
  264. { example: '*', actual: '1', result: '1', },
  265. { example: '*', actual: -0, result: 0, },
  266. { example: '*', actual: +0, result: 0, },
  267. { example: '*', actual: 0, result: 0, },
  268. { example: '*', actual: 1, result: 1, },
  269. { example: '*', actual: -1.1, result: -1.1, },
  270. { example: '*', actual: true, result: true, },
  271. { example: '*', actual: false, result: false, },
  272. { example: '*', actual: {}, result: {}, },
  273. { example: '*', actual: {foo:'bar'}, result: {foo:'bar'}, },
  274. { example: '*', actual: {foo:{bar:{baz:{}}}}, result: {foo:{bar:{baz:{}}}}, },
  275. { example: '*', actual: {foo:['bar']}, result: {foo:['bar']}, },
  276. { example: '*', actual: {foo:{bar:{baz:[{}]}}}, result: {foo:{bar:{baz:[{}]}}}, },
  277. { example: '*', actual: [], result: [], },
  278. { example: '*', actual: ['asdf'], result: ['asdf'], },
  279. { example: '*', actual: [''], result: [''], },
  280. { example: '*', actual: [235], result: [235], },
  281. { example: '*', actual: [false], result: [false], },
  282. { example: '*', actual: [{}], result: [{}], },
  283. { example: '*', actual: [{foo:'bar'}], result: [{foo:'bar'}], },
  284. { example: '*', actual: undefined, error: true, },
  285. { example: '*', actual: NaN, result: 0 },
  286. { example: '*', actual: Infinity, result: 0 },
  287. { example: '*', actual: -Infinity, result: 0 },
  288. { example: '*', actual: null, result: null, },
  289. { example: '*', actual: /some regexp/gi, result: '/some regexp/gi' },
  290. { example: '*', actual: new Date('November 5, 1605 GMT'), result: '1605-11-05T00:00:00.000Z' },
  291. { example: '*', actual: (function(){var err=new Error();err.stack='test';return err;})(), result: 'test' },
  292. { example: '*', actual: function(){}, result: 'function (){}' },
  293. { example: '*', actual: new (require('stream').Readable)(), error: true },
  294. ////////////////////////////////////////////
  295. // RECURSIVE OBJECTS
  296. ////////////////////////////////////////////
  297. // Missing keys (general case)
  298. { example: {a:1, b:'hi', c: false}, actual: {a: 11}, error: true },
  299. { example: {a:1, b:'hi', c: false}, actual: {a: 23, b: undefined, c: undefined}, error: true },
  300. { example: {a:1}, actual: {a: undefined}, error: true },
  301. { example: {a:1}, actual: {}, error: true },
  302. // Missing keys (`===` case)
  303. { example: {a:'==='}, actual: {a: undefined}, error: true },
  304. { example: {a:'==='}, actual: {}, error: true },
  305. // Strip keys with `undefined` values (`{}` case)
  306. { example: {}, actual: {a: undefined, b: 3}, result: {b: 3} },
  307. { example: [{}], actual: [{a: undefined, b: 3}], result: [{b: 3}] },
  308. { example: {x:{}}, actual: {x:{a: undefined, b: 3}}, result: {x:{b: 3}} },
  309. // Don't strip keys with `undefined` values (`===` case)
  310. { example: '===', actual: {a: undefined, b: 3}, result: {a: undefined, b: 3} },
  311. // Extra keys:
  312. { example: {a:1, b:'hi'}, actual: {a: 23, b: 'stuff', d: true}, result: {a: 23, b: 'stuff'} },
  313. { example: {a:1, b:'hi'}, actual: {a: 23, b: 'stuff', d: undefined}, result: {a: 23, b: 'stuff'} },
  314. ////////////////////////////////////////////
  315. // example: ===
  316. ////////////////////////////////////////////
  317. { example: '===', actual: 'bar', result: 'bar', },
  318. { example: '===', actual: '', result: '', },
  319. { example: '===', actual: '-1.1', result: '-1.1', },
  320. { example: '===', actual: 'NaN', result: 'NaN', },
  321. { example: '===', actual: 'undefined', result: 'undefined', },
  322. { example: '===', actual: 'null', result: 'null', },
  323. { example: '===', actual: '-Infinity', result: '-Infinity', },
  324. { example: '===', actual: 'Infinity', result: 'Infinity', },
  325. { example: '===', actual: 'true', result: 'true', },
  326. { example: '===', actual: 'false', result: 'false', },
  327. { example: '===', actual: '0', result: '0', },
  328. { example: '===', actual: '1', result: '1', },
  329. { example: '===', actual: -0, result: -0, },
  330. { example: '===', actual: +0, result: +0, },
  331. { example: '===', actual: 0, result: 0, },
  332. { example: '===', actual: 1, result: 1, },
  333. { example: '===', actual: -1.1, result: -1.1, },
  334. { example: '===', actual: true, result: true, },
  335. { example: '===', actual: false, result: false, },
  336. { example: '===', actual: {}, result: {}, },
  337. { example: '===', actual: {foo:'bar'}, result: {foo:'bar'}, },
  338. { example: '===', actual: {foo:{bar:{baz:{}}}}, result: {foo:{bar:{baz:{}}}}, },
  339. { example: '===', actual: {foo:['bar']}, result: {foo:['bar']}, },
  340. { example: '===', actual: {foo:{bar:{baz:[{}]}}}, result: {foo:{bar:{baz:[{}]}}}, },
  341. { example: '===', actual: [], result: [], },
  342. { example: '===', actual: ['asdf'], result: ['asdf'], },
  343. { example: '===', actual: [''], result: [''], },
  344. { example: '===', actual: [235], result: [235], },
  345. { example: '===', actual: [false], result: [false], },
  346. { example: '===', actual: [{}], result: [{}], },
  347. { example: '===', actual: [{foo:'bar'}], result: [{foo:'bar'}], },
  348. { example: '===', actual: undefined, error: true },
  349. { example: '===', actual: NaN, result: NaN, },
  350. { example: '===', actual: Infinity, result: Infinity, },
  351. { example: '===', actual: -Infinity, result: -Infinity, },
  352. { example: '===', actual: null, result: null, },
  353. ////////////////////////////////////////////
  354. // example: '->'
  355. ////////////////////////////////////////////
  356. { example: '->', actual: 'bar', error: true },
  357. { example: '->', actual: '', error: true },
  358. { example: '->', actual: '-1.1', error: true },
  359. { example: '->', actual: 'NaN', error: true },
  360. { example: '->', actual: 'undefined', error: true },
  361. { example: '->', actual: 'null', error: true },
  362. { example: '->', actual: '-Infinity', error: true },
  363. { example: '->', actual: 'Infinity', error: true },
  364. { example: '->', actual: 'true', error: true },
  365. { example: '->', actual: 'false', error: true },
  366. { example: '->', actual: '0', error: true },
  367. { example: '->', actual: '1', error: true },
  368. { example: '->', actual: -0, error: true },
  369. { example: '->', actual: +0, error: true },
  370. { example: '->', actual: 0, error: true },
  371. { example: '->', actual: 1, error: true },
  372. { example: '->', actual: -1.1, error: true },
  373. { example: '->', actual: true, error: true },
  374. { example: '->', actual: false, error: true },
  375. { example: '->', actual: {}, error: true },
  376. { example: '->', actual: {foo:'bar'}, error: true },
  377. { example: '->', actual: {foo:{bar:{baz:{}}}}, error: true },
  378. { example: '->', actual: {foo:['bar']}, error: true },
  379. { example: '->', actual: {foo:{bar:{baz:[{}]}}}, error: true },
  380. { example: '->', actual: [], error: true },
  381. { example: '->', actual: ['asdf'], error: true },
  382. { example: '->', actual: [''], error: true },
  383. { example: '->', actual: [235], error: true },
  384. { example: '->', actual: [false], error: true },
  385. { example: '->', actual: [{}], error: true },
  386. { example: '->', actual: [{foo:'bar'}], error: true },
  387. { example: '->', actual: undefined, error: true },
  388. { example: '->', actual: NaN, error: true },
  389. { example: '->', actual: Infinity, error: true },
  390. { example: '->', actual: -Infinity, error: true },
  391. { example: '->', actual: null, error: true },
  392. { example: '->', actual: function (inputs, exits){return exits.success();}, result: function (inputs, exits){return exits.success();} },
  393. // $$\
  394. // \__|
  395. // $$$$$$\ $$$$$$\ $$$$$$$\ $$\ $$\ $$$$$$\ $$$$$$$\ $$\ $$\ $$\ $$$$$$\
  396. // $$ __$$\ $$ __$$\ $$ _____|$$ | $$ |$$ __$$\ $$ _____|$$ |\$$\ $$ |$$ __$$\
  397. // $$ | \__|$$$$$$$$ |$$ / $$ | $$ |$$ | \__|\$$$$$$\ $$ | \$$\$$ / $$$$$$$$ |
  398. // $$ | $$ ____|$$ | $$ | $$ |$$ | \____$$\ $$ | \$$$ / $$ ____|
  399. // $$ | \$$$$$$$\ \$$$$$$$\ \$$$$$$ |$$ | $$$$$$$ |$$ | \$ / \$$$$$$$\
  400. // \__| \_______| \_______| \______/ \__| \_______/ \__| \_/ \_______|
  401. //
  402. //
  403. //
  404. // Some basic deep dicts and array
  405. {
  406. example: {a:1, b:'hi', c: false},
  407. actual: {a: 23},
  408. error: true
  409. },
  410. {
  411. example: {a:1, b:'hi', c: false},
  412. actual: {a: 23, d: true},
  413. error: true
  414. },
  415. // Ensure that this allows extra keys when coercing to `example: {}`
  416. {
  417. example: {},
  418. actual: {a: 23, d: true},
  419. result: {a: 23, d: true}
  420. },
  421. // Omit extra keys when coercing to `example: {...}`
  422. {
  423. example: { a:23 },
  424. actual: {a: 23, d: true},
  425. result: {a: 23}
  426. },
  427. // Reject when there are missing or undefined required keys
  428. { example: {b: 235}, actual: {b: undefined}, error: true },
  429. { example: {b: 235}, actual: {}, error: true },
  430. // Strip extra keys with `undefined` values (`{...}` case)
  431. { example: {b: 235}, actual: {a: undefined, b: 3}, result: {b: 3} },
  432. // Strip extra nested keys with `undefined` values (`{...}` case)
  433. { example: {a: {}, b: 235}, actual: {a: {x: undefined}, b: 3}, result: {a: {}, b: 3} },
  434. // Strip keys with `undefined` values (`{}` case)
  435. { example: {}, actual: {a: undefined, b: 3}, result: {b: 3} },
  436. // Strip nested keys with `undefined` values (`{}` case)
  437. { example: {}, actual: {a: {x: undefined}, b: 3}, result: {a: {}, b: 3} },
  438. // Don't strip keys or nested keys with `undefined` values (`===` and nested `===` cases)
  439. { example: '===', actual: {a: undefined, b: 3, c: {x: undefined}}, result: {a: undefined, b: 3, c: {x: undefined}} },
  440. { example: {c:'==='}, actual: {a: undefined, b: 3, c: {x: undefined}}, result: { c: {x: undefined}} },
  441. // Ensure that this allows arbitary arrays when coercing to `example: []`
  442. {
  443. example: [],
  444. actual: [{a: 23, d: true}],
  445. result: [{a: 23, d: true}]
  446. },
  447. // Ensure that nested dictionaries inside of an array passed
  448. // through `example: []` are stripped of keys with undefined values
  449. {
  450. example: [],
  451. actual: [{a:3, b: undefined}, {a: undefined}],
  452. result: [{a: 3},{}]
  453. },
  454. {
  455. example: [],
  456. actual: [{a:3,someStuff: [{x: undefined, y: 'foo'}, {x: 'bar', y: undefined}]},{a: 5, b: undefined}],
  457. result: [{a: 3, someStuff: [{y:'foo'}, {x:'bar'}]}, {a: 5}]
  458. },
  459. // Prune `undefined` items from arrays and nested arrays (`[]` case)
  460. {
  461. example: [],
  462. actual: [{a:3}, undefined, {a: 5}, undefined, {a: 7}, {a:9, b: [undefined, 9,2,4,undefined,8]}],
  463. result: [{a: 3}, {a: 5}, {a:7}, {a:9, b:[9,2,4,8]}]
  464. },
  465. // DO allow `undefined` items from arrays and nested arrays (`===` case)
  466. {
  467. example: '===',
  468. actual: [{a:3}, undefined, {a: 5}, undefined, {a: 7}, {a:9, b: [undefined, 9,2,4,undefined,8]}],
  469. result: [{a:3}, undefined, {a: 5}, undefined, {a: 7}, {a:9, b: [undefined, 9,2,4,undefined,8]}]
  470. },
  471. // Don't allow `undefined` items from arrays and nested arrays (`[===]` case)
  472. // (because '===' does not allow `undefined`)
  473. {
  474. example: ['==='],
  475. actual: [{a:3}, undefined, {a: 5}, undefined, {a: 7}, {a:9, b: [undefined, 9,2,4,undefined,8]}],
  476. result: [{a:3}, {a: 5}, {a: 7}, {a:9, b: [undefined, 9,2,4,undefined,8]}]
  477. },
  478. // Ensure that nested dictionaries inside of an array passed
  479. // through `example: ['===']` are NOT stripped of keys with undefined values--
  480. // and are left utterly alone
  481. {
  482. example: ['==='],
  483. actual: [{a:3, b: undefined}, {a: undefined}],
  484. result: [{a: 3, b: undefined},{a:undefined}]
  485. },
  486. {
  487. example: ['==='],
  488. actual: [{a:3,someStuff: [{x: undefined, y: 'foo'}, {x: 'bar', y: undefined}]},{a: 5, b: undefined}],
  489. result: [{a:3,someStuff: [{x: undefined, y: 'foo'}, {x: 'bar', y: undefined}]},{a: 5, b: undefined}]
  490. },
  491. // Ensure the recursive cloning / undefined-key-stripping doesn't get
  492. // stumped by circular dictionaries/arrays.
  493. // • dict keys whose values point to a past reference should be deleted
  494. // • array items that point to past references should be pruned
  495. (function (){
  496. var someDict = {};
  497. var someArray = [];
  498. someDict.x = {z: someDict, foo: undefined};
  499. someDict.y = someArray;
  500. someArray.push(someDict);
  501. someArray.push(someDict.x);
  502. var test = {
  503. example: {},
  504. actual: {
  505. someDict: someDict,
  506. someArray: someArray
  507. },
  508. result: {
  509. someDict: {
  510. x: {
  511. z: '[Circular ~.someDict]'
  512. },
  513. y: [
  514. '[Circular ~.someDict]',
  515. {
  516. z: '[Circular ~.someDict]'
  517. }
  518. ]
  519. },
  520. someArray: [
  521. {
  522. x: {
  523. z: '[Circular ~.someArray.0]'
  524. },
  525. y: '[Circular ~.someArray]'
  526. },
  527. {
  528. z: {
  529. x: '[Circular ~.someArray.1]',
  530. y: '[Circular ~.someArray]'
  531. }
  532. }
  533. ]
  534. }
  535. };
  536. return test;
  537. })(),
  538. {
  539. example: [{}],
  540. actual: [ { name: 'Lucy' }, { name: 'Ricky' }, { name: 'Louise' }, { name: 'Estelle' } ],
  541. expected: [ { name: 'Lucy' }, { name: 'Ricky' }, { name: 'Louise' }, { name: 'Estelle' } ]
  542. },
  543. // $$\ $$\ $$\ $$$\ $$$\
  544. // $$ | \__| $$ | $$ _| \$$\
  545. // $$$$$$$\ $$$$$$\ $$$$$$\ $$\ $$$$$$$\ $$$$$$\ $$$$$$\ $$$$$$\ $$ /$$$$\ $$$$\ $$$$\ \$$\
  546. // $$ _____|\_$$ _| $$ __$$\ $$ |$$ _____|\_$$ _| $$ __$$\ $$ __$$\ $$ | \____|\____|\____| $$ |
  547. // \$$$$$$\ $$ | $$ | \__|$$ |$$ / $$ | $$$$$$$$ |$$ / $$ | $$ | $$$$\ $$$$\ $$$$\ $$ |
  548. // \____$$\ $$ |$$\ $$ | $$ |$$ | $$ |$$\ $$ ____|$$ | $$ | \$$\ \____|\____|\____|$$ |
  549. // $$$$$$$ | \$$$$ |$$ | $$ |\$$$$$$$\ \$$$$ | \$$$$$$$\ \$$$$$$$ | \$$$\ $$$ /
  550. // \_______/ \____/ \__| \__| \_______| \____/ \_______| \____$$ | \___| \___/
  551. // $$ |
  552. // $$ |
  553. // \__|
  554. //
  555. // (strictEq / isNew checks to assert for and
  556. // against passing-by-reference in different
  557. // situations)
  558. ////////////////////////////////////////////////
  559. { example: '===', actual: /some regexp/, strictEq: true },
  560. { example: '===', actual: function (){}, strictEq: true },
  561. { example: '===', actual: new Date('November 5, 1605 GMT'), strictEq: true },
  562. { example: '===', actual: new (require('stream').Readable)(), strictEq: true },
  563. { example: '===', actual: new Buffer('asdf'), strictEq: true },
  564. { example: '===', actual: new Error('asdf'), strictEq: true },
  565. ];