is-specific.test.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. var util = require('util');
  2. var assert = require('assert');
  3. var _ = require('@sailshq/lodash');
  4. var rttc = require('../');
  5. describe('.isSpecific()', function() {
  6. // TODO: test that this doesn't go nuts given circular objects
  7. // (they should never be circular because they are type schemas, but still, for everyone's sanity)
  8. describe('using type schemas', function (){
  9. it('should consider string SPECIFIC', function() {
  10. assert(rttc.isSpecific('string'));
  11. });
  12. it('should consider number SPECIFIC', function() {
  13. assert(rttc.isSpecific('string'));
  14. });
  15. it('should consider boolean SPECIFIC', function() {
  16. assert(rttc.isSpecific('boolean'));
  17. });
  18. it('should consider lamda SPECIFIC', function() {
  19. assert(rttc.isSpecific('lamda'));
  20. });
  21. it('should consider generic dictionary NOT SPECIFIC', function() {
  22. assert(! rttc.isSpecific({}) );
  23. });
  24. it('should consider generic array NOT SPECIFIC', function() {
  25. assert(! rttc.isSpecific([]) );
  26. });
  27. it('should consider patterned dictionaries SPECIFIC', function() {
  28. assert(rttc.isSpecific({x: 'string'}) );
  29. assert(rttc.isSpecific({y:'number'}) );
  30. assert(rttc.isSpecific({z: 'boolean'}) );
  31. assert(rttc.isSpecific({l: 'lamda'}) );
  32. assert(rttc.isSpecific({foo:'string', bar: 'boolean', baz: 'number'}) );
  33. assert(rttc.isSpecific({x: ['string'], y: ['number'], z: ['boolean'], l:{a:{m:{d:{a:'lamda'}}}} }) );
  34. });
  35. it('should consider patterned arrays SPECIFIC', function() {
  36. assert(rttc.isSpecific(['string']) );
  37. assert(rttc.isSpecific(['number']) );
  38. assert(rttc.isSpecific(['boolean']) );
  39. assert(rttc.isSpecific(['lamda']) );
  40. assert(rttc.isSpecific([{foo:'string', bar: 'boolean', baz: 'number'}]) );
  41. assert(rttc.isSpecific([['string']]) );
  42. assert(rttc.isSpecific([['number']]) );
  43. assert(rttc.isSpecific([['boolean']]) );
  44. assert(rttc.isSpecific([['lamda']]) );
  45. assert(rttc.isSpecific([[{foo:'string', bar: 'boolean', baz: 'number'}]]) );
  46. });
  47. it('should consider json NOT SPECIFIC', function() {
  48. assert(! rttc.isSpecific('json') );
  49. });
  50. it('should consider ref NOT SPECIFIC', function() {
  51. assert(! rttc.isSpecific('ref') );
  52. });
  53. it('should consider faceted/patterned things with nested json,ref,[],and {} as SPECIFIC by default', function (){
  54. assert(rttc.isSpecific({saltySurprise: 'json', x: 'string'}) );
  55. assert(rttc.isSpecific({saltySurprise: 'json', y:'number'}) );
  56. assert(rttc.isSpecific({saltySurprise: 'json', z: 'boolean'}) );
  57. assert(rttc.isSpecific({saltySurprise: 'json', l: 'lamda'}) );
  58. assert(rttc.isSpecific({saltySurprise: 'json', foo:'string', bar: 'boolean', baz: 'number'}) );
  59. assert(rttc.isSpecific({saltySurprise: 'json', x: ['string'], y: ['number'], z: ['boolean'], l:{a:{m:{d:{a:'lamda'}}}} }) );
  60. assert(rttc.isSpecific([{saltySurprise: 'json', x: ['string'], y: ['number'], z: ['boolean'], l:{a:{m:{d:{a:'lamda'}}}} }]) );
  61. assert(rttc.isSpecific(['json']) );
  62. assert(rttc.isSpecific([['json']]) );
  63. assert(rttc.isSpecific({saltySurprise: 'ref', x: 'string'}) );
  64. assert(rttc.isSpecific({saltySurprise: 'ref', y:'number'}) );
  65. assert(rttc.isSpecific({saltySurprise: 'ref', z: 'boolean'}) );
  66. assert(rttc.isSpecific({saltySurprise: 'ref', l: 'lamda'}) );
  67. assert(rttc.isSpecific({saltySurprise: 'ref', foo:'string', bar: 'boolean', baz: 'number'}) );
  68. assert(rttc.isSpecific({saltySurprise: 'ref', x: ['string'], y: ['number'], z: ['boolean'], l:{a:{m:{d:{a:'lamda'}}}} }) );
  69. assert(rttc.isSpecific([{saltySurprise: 'ref', x: ['string'], y: ['number'], z: ['boolean'], l:{a:{m:{d:{a:'lamda'}}}} }]) );
  70. assert(rttc.isSpecific(['ref']) );
  71. assert(rttc.isSpecific([['ref']]) );
  72. assert(rttc.isSpecific({saltySurprise: {}, x: 'string'}) );
  73. assert(rttc.isSpecific({saltySurprise: {}, y:'number'}) );
  74. assert(rttc.isSpecific({saltySurprise: {}, z: 'boolean'}) );
  75. assert(rttc.isSpecific({saltySurprise: {}, l: 'lamda'}) );
  76. assert(rttc.isSpecific({saltySurprise: {}, foo:'string', bar: 'boolean', baz: 'number'}) );
  77. assert(rttc.isSpecific({saltySurprise: {}, x: ['string'], y: ['number'], z: ['boolean'], l:{a:{m:{d:{a:'lamda'}}}} }) );
  78. assert(rttc.isSpecific([{saltySurprise: {}, x: ['string'], y: ['number'], z: ['boolean'], l:{a:{m:{d:{a:'lamda'}}}} }]) );
  79. assert(rttc.isSpecific([{}]) );
  80. assert(rttc.isSpecific([[{}]]) );
  81. assert(rttc.isSpecific({saltySurprise: [], x: 'string'}) );
  82. assert(rttc.isSpecific({saltySurprise: [], y:'number'}) );
  83. assert(rttc.isSpecific({saltySurprise: [], z: 'boolean'}) );
  84. assert(rttc.isSpecific({saltySurprise: [], l: 'lamda'}) );
  85. assert(rttc.isSpecific({saltySurprise: [], foo:'string', bar: 'boolean', baz: 'number'}) );
  86. assert(rttc.isSpecific({saltySurprise: [], x: ['string'], y: ['number'], z: ['boolean'], l:{a:{m:{d:{a:'lamda'}}}} }) );
  87. assert(rttc.isSpecific([{saltySurprise: [], x: ['string'], y: ['number'], z: ['boolean'], l:{a:{m:{d:{a:'lamda'}}}} }]) );
  88. assert(rttc.isSpecific([[]]) );
  89. assert(rttc.isSpecific([[[]]]) );
  90. });
  91. it('should consider faceted/patterned things with nested json,ref,[],and {} as NOT SPECIFIC if recursive flag is set', function (){
  92. assert(! rttc.isSpecific({saltySurprise: 'json', x: 'string'}, true) );
  93. assert(! rttc.isSpecific({saltySurprise: 'json', y:'number'}, true) );
  94. assert(! rttc.isSpecific({saltySurprise: 'json', z: 'boolean'}, true) );
  95. assert(! rttc.isSpecific({saltySurprise: 'json', l: 'lamda'}, true) );
  96. assert(! rttc.isSpecific({saltySurprise: 'json', foo:'string', bar: 'boolean', baz: 'number'}, true) );
  97. assert(! rttc.isSpecific({saltySurprise: 'json', x: ['string'], y: ['number'], z: ['boolean'], l:{a:{m:{d:{a:'lamda'}}}} }, true) );
  98. assert(! rttc.isSpecific([{saltySurprise: 'json', x: ['string'], y: ['number'], z: ['boolean'], l:{a:{m:{d:{a:'lamda'}}}} }], true) );
  99. assert(! rttc.isSpecific(['json'], true) );
  100. assert(! rttc.isSpecific([['json']], true) );
  101. assert(! rttc.isSpecific({saltySurprise: 'ref', x: 'string'}, true) );
  102. assert(! rttc.isSpecific({saltySurprise: 'ref', y:'number'}, true) );
  103. assert(! rttc.isSpecific({saltySurprise: 'ref', z: 'boolean'}, true) );
  104. assert(! rttc.isSpecific({saltySurprise: 'ref', l: 'lamda'}, true) );
  105. assert(! rttc.isSpecific({saltySurprise: 'ref', foo:'string', bar: 'boolean', baz: 'number'}, true) );
  106. assert(! rttc.isSpecific({saltySurprise: 'ref', x: ['string'], y: ['number'], z: ['boolean'], l:{a:{m:{d:{a:'lamda'}}}} }, true) );
  107. assert(! rttc.isSpecific([{saltySurprise: 'ref', x: ['string'], y: ['number'], z: ['boolean'], l:{a:{m:{d:{a:'lamda'}}}} }], true) );
  108. assert(! rttc.isSpecific(['ref'], true) );
  109. assert(! rttc.isSpecific([['ref']], true) );
  110. assert(! rttc.isSpecific({saltySurprise: {}, x: 'string'}, true) );
  111. assert(! rttc.isSpecific({saltySurprise: {}, y:'number'}, true) );
  112. assert(! rttc.isSpecific({saltySurprise: {}, z: 'boolean'}, true) );
  113. assert(! rttc.isSpecific({saltySurprise: {}, l: 'lamda'}, true) );
  114. assert(! rttc.isSpecific({saltySurprise: {}, foo:'string', bar: 'boolean', baz: 'number'}, true) );
  115. assert(! rttc.isSpecific({saltySurprise: {}, x: ['string'], y: ['number'], z: ['boolean'], l:{a:{m:{d:{a:'lamda'}}}} }, true) );
  116. assert(! rttc.isSpecific([{saltySurprise: {}, x: ['string'], y: ['number'], z: ['boolean'], l:{a:{m:{d:{a:'lamda'}}}} }], true) );
  117. assert(! rttc.isSpecific([{}], true) );
  118. assert(! rttc.isSpecific([[{}]], true) );
  119. assert(! rttc.isSpecific({saltySurprise: [], x: 'string'}, true) );
  120. assert(! rttc.isSpecific({saltySurprise: [], y:'number'}, true) );
  121. assert(! rttc.isSpecific({saltySurprise: [], z: 'boolean'}, true) );
  122. assert(! rttc.isSpecific({saltySurprise: [], l: 'lamda'}, true) );
  123. assert(! rttc.isSpecific({saltySurprise: [], foo:'string', bar: 'boolean', baz: 'number'}, true) );
  124. assert(! rttc.isSpecific({saltySurprise: [], x: ['string'], y: ['number'], z: ['boolean'], l:{a:{m:{d:{a:'lamda'}}}} }, true) );
  125. assert(! rttc.isSpecific([{saltySurprise: [], x: ['string'], y: ['number'], z: ['boolean'], l:{a:{m:{d:{a:'lamda'}}}} }], true) );
  126. assert(! rttc.isSpecific([[]], true) );
  127. assert(! rttc.isSpecific([[[]]], true) );
  128. });
  129. });
  130. describe('using exemplar schemas', function (){
  131. it('should consider string SPECIFIC', function() {
  132. assert(rttc.isSpecific('Regis Philbin', undefined, true));
  133. });
  134. it('should consider number SPECIFIC', function() {
  135. assert(rttc.isSpecific(130, undefined, true));
  136. });
  137. it('should consider boolean SPECIFIC', function() {
  138. assert(rttc.isSpecific(false, undefined, true));
  139. });
  140. it('should consider lamda SPECIFIC', function() {
  141. assert(rttc.isSpecific('->', undefined, true));
  142. });
  143. it('should consider generic dictionary NOT SPECIFIC', function() {
  144. assert(! rttc.isSpecific({}, undefined, true) );
  145. });
  146. it('should consider generic array NOT SPECIFIC', function() {
  147. assert(! rttc.isSpecific([], undefined, true) );
  148. });
  149. it('should consider patterned dictionaries SPECIFIC', function() {
  150. assert(rttc.isSpecific({x: 'Regis Philbin'}, undefined, true) );
  151. assert(rttc.isSpecific({y:130}, undefined, true) );
  152. assert(rttc.isSpecific({z: false}, undefined, true) );
  153. assert(rttc.isSpecific({l: '->'}, undefined, true) );
  154. assert(rttc.isSpecific({foo:'Regis Philbin', bar: false, baz: 130}, undefined, true) );
  155. assert(rttc.isSpecific({x: ['Regis Philbin'], y: [130], z: [false], l:{a:{m:{d:{a:'->'}}}} }, undefined, true) );
  156. });
  157. it('should consider patterned arrays SPECIFIC', function() {
  158. assert(rttc.isSpecific(['Regis Philbin'], undefined, true) );
  159. assert(rttc.isSpecific([130], undefined, true) );
  160. assert(rttc.isSpecific([false], undefined, true) );
  161. assert(rttc.isSpecific(['->'], undefined, true) );
  162. assert(rttc.isSpecific([{foo:'Regis Philbin', bar: false, baz: 130}], undefined, true) );
  163. assert(rttc.isSpecific([['Regis Philbin']], undefined, true) );
  164. assert(rttc.isSpecific([[130]], undefined, true) );
  165. assert(rttc.isSpecific([[false]], undefined, true) );
  166. assert(rttc.isSpecific([['->']], undefined, true) );
  167. assert(rttc.isSpecific([[{foo:'Regis Philbin', bar: false, baz: 130}]], undefined, true) );
  168. });
  169. it('should consider json NOT SPECIFIC', function() {
  170. assert(! rttc.isSpecific('*', undefined, true) );
  171. });
  172. it('should consider ref NOT SPECIFIC', function() {
  173. assert(! rttc.isSpecific('===', undefined, true) );
  174. });
  175. it('should consider faceted/patterned things with nested json,ref,[],and {} as SPECIFIC by default', function (){
  176. assert(rttc.isSpecific({saltySurprise: '*', x: 'Regis Philbin'}, undefined, true) );
  177. assert(rttc.isSpecific({saltySurprise: '*', y:130}, undefined, true) );
  178. assert(rttc.isSpecific({saltySurprise: '*', z: false}, undefined, true) );
  179. assert(rttc.isSpecific({saltySurprise: '*', l: '->'}, undefined, true) );
  180. assert(rttc.isSpecific({saltySurprise: '*', foo:'Regis Philbin', bar: false, baz: 130}, undefined, true) );
  181. assert(rttc.isSpecific({saltySurprise: '*', x: ['Regis Philbin'], y: [130], z: [false], l:{a:{m:{d:{a:'->'}}}} }, undefined, true) );
  182. assert(rttc.isSpecific([{saltySurprise: '*', x: ['Regis Philbin'], y: [130], z: [false], l:{a:{m:{d:{a:'->'}}}} }], undefined, true) );
  183. assert(rttc.isSpecific(['*'], undefined, true) );
  184. assert(rttc.isSpecific([['*']], undefined, true) );
  185. assert(rttc.isSpecific({saltySurprise: '===', x: 'Regis Philbin'}, undefined, true) );
  186. assert(rttc.isSpecific({saltySurprise: '===', y:130}, undefined, true) );
  187. assert(rttc.isSpecific({saltySurprise: '===', z: false}, undefined, true) );
  188. assert(rttc.isSpecific({saltySurprise: '===', l: '->'}, undefined, true) );
  189. assert(rttc.isSpecific({saltySurprise: '===', foo:'Regis Philbin', bar: false, baz: 130}, undefined, true) );
  190. assert(rttc.isSpecific({saltySurprise: '===', x: ['Regis Philbin'], y: [130], z: [false], l:{a:{m:{d:{a:'->'}}}} }, undefined, true) );
  191. assert(rttc.isSpecific([{saltySurprise: '===', x: ['Regis Philbin'], y: [130], z: [false], l:{a:{m:{d:{a:'->'}}}} }], undefined, true) );
  192. assert(rttc.isSpecific(['==='], undefined, true) );
  193. assert(rttc.isSpecific([['===']], undefined, true) );
  194. assert(rttc.isSpecific({saltySurprise: {}, x: 'Regis Philbin'}, undefined, true) );
  195. assert(rttc.isSpecific({saltySurprise: {}, y:130}, undefined, true) );
  196. assert(rttc.isSpecific({saltySurprise: {}, z: false}, undefined, true) );
  197. assert(rttc.isSpecific({saltySurprise: {}, l: '->'}, undefined, true) );
  198. assert(rttc.isSpecific({saltySurprise: {}, foo:'Regis Philbin', bar: false, baz: 130}, undefined, true) );
  199. assert(rttc.isSpecific({saltySurprise: {}, x: ['Regis Philbin'], y: [130], z: [false], l:{a:{m:{d:{a:'->'}}}} }, undefined, true) );
  200. assert(rttc.isSpecific([{saltySurprise: {}, x: ['Regis Philbin'], y: [130], z: [false], l:{a:{m:{d:{a:'->'}}}} }], undefined, true) );
  201. assert(rttc.isSpecific([{}], undefined, true) );
  202. assert(rttc.isSpecific([[{}]], undefined, true) );
  203. assert(rttc.isSpecific({saltySurprise: [], x: 'Regis Philbin'}, undefined, true) );
  204. assert(rttc.isSpecific({saltySurprise: [], y:130}, undefined, true) );
  205. assert(rttc.isSpecific({saltySurprise: [], z: false}, undefined, true) );
  206. assert(rttc.isSpecific({saltySurprise: [], l: '->'}, undefined, true) );
  207. assert(rttc.isSpecific({saltySurprise: [], foo:'Regis Philbin', bar: false, baz: 130}, undefined, true) );
  208. assert(rttc.isSpecific({saltySurprise: [], x: ['Regis Philbin'], y: [130], z: [false], l:{a:{m:{d:{a:'->'}}}} }, undefined, true) );
  209. assert(rttc.isSpecific([{saltySurprise: [], x: ['Regis Philbin'], y: [130], z: [false], l:{a:{m:{d:{a:'->'}}}} }], undefined, true) );
  210. assert(rttc.isSpecific([[]], undefined, true) );
  211. assert(rttc.isSpecific([[[]]], undefined, true) );
  212. });
  213. it('should consider faceted/patterned things with nested json,ref,[],and {} as NOT SPECIFIC if recursive flag is set', function (){
  214. assert(! rttc.isSpecific({saltySurprise: '*', x: 'Regis Philbin'}, true, true) );
  215. assert(! rttc.isSpecific({saltySurprise: '*', y:130}, true, true) );
  216. assert(! rttc.isSpecific({saltySurprise: '*', z: false}, true, true) );
  217. assert(! rttc.isSpecific({saltySurprise: '*', l: '->'}, true, true) );
  218. assert(! rttc.isSpecific({saltySurprise: '*', foo:'Regis Philbin', bar: false, baz: 130}, true, true) );
  219. assert(! rttc.isSpecific({saltySurprise: '*', x: ['Regis Philbin'], y: [130], z: [false], l:{a:{m:{d:{a:'->'}}}} }, true, true) );
  220. assert(! rttc.isSpecific([{saltySurprise: '*', x: ['Regis Philbin'], y: [130], z: [false], l:{a:{m:{d:{a:'->'}}}} }], true, true) );
  221. assert(! rttc.isSpecific(['*'], true, true) );
  222. assert(! rttc.isSpecific([['*']], true, true) );
  223. assert(! rttc.isSpecific({saltySurprise: '===', x: 'Regis Philbin'}, true, true) );
  224. assert(! rttc.isSpecific({saltySurprise: '===', y:130}, true, true) );
  225. assert(! rttc.isSpecific({saltySurprise: '===', z: false}, true, true) );
  226. assert(! rttc.isSpecific({saltySurprise: '===', l: '->'}, true, true) );
  227. assert(! rttc.isSpecific({saltySurprise: '===', foo:'Regis Philbin', bar: false, baz: 130}, true, true) );
  228. assert(! rttc.isSpecific({saltySurprise: '===', x: ['Regis Philbin'], y: [130], z: [false], l:{a:{m:{d:{a:'->'}}}} }, true, true) );
  229. assert(! rttc.isSpecific([{saltySurprise: '===', x: ['Regis Philbin'], y: [130], z: [false], l:{a:{m:{d:{a:'->'}}}} }], true, true) );
  230. assert(! rttc.isSpecific(['==='], true, true) );
  231. assert(! rttc.isSpecific([['===']], true, true) );
  232. assert(! rttc.isSpecific({saltySurprise: {}, x: 'Regis Philbin'}, true, true) );
  233. assert(! rttc.isSpecific({saltySurprise: {}, y:130}, true, true) );
  234. assert(! rttc.isSpecific({saltySurprise: {}, z: false}, true, true) );
  235. assert(! rttc.isSpecific({saltySurprise: {}, l: '->'}, true, true) );
  236. assert(! rttc.isSpecific({saltySurprise: {}, foo:'Regis Philbin', bar: false, baz: 130}, true, true) );
  237. assert(! rttc.isSpecific({saltySurprise: {}, x: ['Regis Philbin'], y: [130], z: [false], l:{a:{m:{d:{a:'->'}}}} }, true, true) );
  238. assert(! rttc.isSpecific([{saltySurprise: {}, x: ['Regis Philbin'], y: [130], z: [false], l:{a:{m:{d:{a:'->'}}}} }], true, true) );
  239. assert(! rttc.isSpecific([{}], true, true) );
  240. assert(! rttc.isSpecific([[{}]], true, true) );
  241. assert(! rttc.isSpecific({saltySurprise: [], x: 'Regis Philbin'}, true, true) );
  242. assert(! rttc.isSpecific({saltySurprise: [], y:130}, true, true) );
  243. assert(! rttc.isSpecific({saltySurprise: [], z: false}, true, true) );
  244. assert(! rttc.isSpecific({saltySurprise: [], l: '->'}, true, true) );
  245. assert(! rttc.isSpecific({saltySurprise: [], foo:'Regis Philbin', bar: false, baz: 130}, true, true) );
  246. assert(! rttc.isSpecific({saltySurprise: [], x: ['Regis Philbin'], y: [130], z: [false], l:{a:{m:{d:{a:'->'}}}} }, true, true) );
  247. assert(! rttc.isSpecific([{saltySurprise: [], x: ['Regis Philbin'], y: [130], z: [false], l:{a:{m:{d:{a:'->'}}}} }], true, true) );
  248. assert(! rttc.isSpecific([[]], true, true) );
  249. assert(! rttc.isSpecific([[[]]], true, true) );
  250. });
  251. });
  252. });