customPoliciesTest.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. var should = require('chai').should();
  2. var rulesChecker = require('../../lib/rulesChecker');
  3. describe('rulesChecker', function() {
  4. var policies = require('../../lib/metadata/policies.js');
  5. var results;
  6. it('should transform DOMelementMaxDepth offenders', function() {
  7. results = rulesChecker.check({
  8. "toolsResults": {
  9. "phantomas": {
  10. "metrics": {
  11. "DOMelementMaxDepth": 3
  12. },
  13. "offenders": {
  14. "DOMelementMaxDepth": [
  15. "body > div#foo > span.bar"
  16. ]
  17. }
  18. }
  19. }
  20. }, policies);
  21. results.should.have.a.property('DOMelementMaxDepth');
  22. results.DOMelementMaxDepth.should.have.a.property('offendersObj').that.deep.equals({
  23. "count": 1,
  24. "tree": {
  25. "body": {
  26. "div#foo": {
  27. "span.bar": 1
  28. }
  29. }
  30. }
  31. });
  32. });
  33. it('should transform DOMidDuplicated offenders', function() {
  34. results = rulesChecker.check({
  35. "toolsResults": {
  36. "phantomas": {
  37. "metrics": {
  38. "DOMidDuplicated": 2
  39. },
  40. "offenders": {
  41. "DOMidDuplicated": [
  42. "colorswitch-30883-30865: 4 occurrences",
  43. "foo: 1 occurrences"
  44. ]
  45. }
  46. }
  47. }
  48. }, policies);
  49. results.should.have.a.property('DOMidDuplicated');
  50. results.DOMidDuplicated.should.have.a.property('offendersObj').that.deep.equals({
  51. "count": 2,
  52. "list": [
  53. {
  54. "id": "colorswitch-30883-30865",
  55. "occurrences": 4
  56. },
  57. {
  58. "id": "foo",
  59. "occurrences": 1
  60. }
  61. ]
  62. });
  63. });
  64. it('should transform DOMinserts offenders', function() {
  65. results = rulesChecker.check({
  66. "toolsResults": {
  67. "phantomas": {
  68. "metrics": {
  69. "DOMinserts": 4
  70. },
  71. "offenders": {
  72. "DOMinserts": [
  73. "\"div\" appended to \"html\"",
  74. "\"DocumentFragment > link[0]\" appended to \"head\"",
  75. "\"div#Netaff-yh1XbS0vK3NaRGu\" appended to \"body > div#Global\"",
  76. "\"img\" appended to \"body\""
  77. ]
  78. }
  79. }
  80. }
  81. }, policies);
  82. results.should.have.a.property('DOMinserts');
  83. results.DOMinserts.should.have.a.property('offendersObj').that.deep.equals({
  84. "count": 4,
  85. "list": [
  86. {
  87. "insertedElement": {
  88. "type": "createdElement",
  89. "element": "div"
  90. },
  91. "receiverElement": {
  92. "type": "html"
  93. }
  94. },
  95. {
  96. "insertedElement": {
  97. "type": "fragmentElement",
  98. "element": "link[0]",
  99. "tree": {
  100. "DocumentFragment": {
  101. "link[0]": 1
  102. }
  103. }
  104. },
  105. "receiverElement": {
  106. "type": "head"
  107. }
  108. },
  109. {
  110. "insertedElement": {
  111. "type": "createdElement",
  112. "element": "div#Netaff-yh1XbS0vK3NaRGu"
  113. },
  114. "receiverElement": {
  115. "type": "domElement",
  116. "element": "div#Global",
  117. "tree": {
  118. "body": {
  119. "div#Global": 1
  120. }
  121. }
  122. }
  123. },
  124. {
  125. "insertedElement": {
  126. "type": "createdElement",
  127. "element": "img"
  128. },
  129. "receiverElement": {
  130. "type": "body"
  131. }
  132. }
  133. ]
  134. });
  135. });
  136. it('should transform DOMqueriesWithoutResults offenders', function() {
  137. results = rulesChecker.check({
  138. "toolsResults": {
  139. "phantomas": {
  140. "metrics": {
  141. "DOMqueriesWithoutResults": 2
  142. },
  143. "offenders": {
  144. "DOMqueriesWithoutResults": [
  145. "#SearchMenu (in #document) using getElementById",
  146. ".partnership-link (in body > div#Global > div#Header > ul#MainMenu) using getElementsByClassName"
  147. ]
  148. }
  149. }
  150. }
  151. }, policies);
  152. results.should.have.a.property('DOMqueriesWithoutResults');
  153. results.DOMqueriesWithoutResults.should.have.a.property('offendersObj').that.deep.equals({
  154. "count": 2,
  155. "list": [
  156. {
  157. "context": {
  158. "type": "document"
  159. },
  160. "fn": "getElementById",
  161. "query": "#SearchMenu "
  162. },
  163. {
  164. "context": {
  165. "element": "ul#MainMenu",
  166. "tree": {
  167. "body": {
  168. "div#Global": {
  169. "div#Header": {
  170. "ul#MainMenu": 1
  171. }
  172. }
  173. }
  174. },
  175. "type": "domElement"
  176. },
  177. "fn": "getElementsByClassName",
  178. "query": ".partnership-link "
  179. }
  180. ]
  181. });
  182. });
  183. it('should transform DOMqueriesAvoidable offenders', function() {
  184. results = rulesChecker.check({
  185. "toolsResults": {
  186. "phantomas": {
  187. "metrics": {
  188. "DOMqueriesAvoidable": 2
  189. },
  190. "offenders": {
  191. "DOMqueriesDuplicated": [
  192. "id \"#j2t-top-cart\" with getElementById (in context #document): 4 queries",
  193. "class \".listingResult\" with getElementsByClassName (in context body > div#Global > div#Listing): 4 queries"
  194. ]
  195. }
  196. }
  197. }
  198. }, policies);
  199. results.should.have.a.property('DOMqueriesAvoidable');
  200. results.DOMqueriesAvoidable.should.have.a.property('offendersObj').that.deep.equals({
  201. "count": 2,
  202. "list": [
  203. {
  204. "query": "#j2t-top-cart",
  205. "context": {
  206. "type": "document"
  207. },
  208. "fn": "getElementById ",
  209. "count": 4
  210. },
  211. {
  212. "query": ".listingResult",
  213. "context": {
  214. "type": "domElement",
  215. "element": "div#Listing",
  216. "tree": {
  217. "body": {
  218. "div#Global": {
  219. "div#Listing": 1
  220. }
  221. }
  222. }
  223. },
  224. "fn": "getElementsByClassName ",
  225. "count": 4
  226. }
  227. ]
  228. });
  229. });
  230. it('should transform eventsBound offenders', function() {
  231. results = rulesChecker.check({
  232. "toolsResults": {
  233. "phantomas": {
  234. "metrics": {
  235. "eventsBound": 2
  236. },
  237. "offenders": {
  238. "eventsBound": [
  239. "\"DOMContentLoaded\" bound to \"#document\"",
  240. "\"unload\" bound to \"window\"",
  241. "\"submit\" bound to \"body > div#Global > div#Header > form#search_mini_form\""
  242. ]
  243. }
  244. }
  245. }
  246. }, policies);
  247. results.should.have.a.property('eventsBound');
  248. results.eventsBound.should.have.a.property('offendersObj').that.deep.equals({
  249. "count": 3,
  250. "list": [
  251. {
  252. "element": {
  253. "type": "document"
  254. },
  255. "eventName": "DOMContentLoaded"
  256. },
  257. {
  258. "element": {
  259. "type": "window"
  260. },
  261. "eventName": "unload"
  262. },
  263. {
  264. "element": {
  265. "element": "form#search_mini_form",
  266. "tree": {
  267. "body": {
  268. "div#Global": {
  269. "div#Header": {
  270. "form#search_mini_form": 1
  271. }
  272. }
  273. }
  274. },
  275. "type": "domElement"
  276. },
  277. "eventName": "submit"
  278. }
  279. ]
  280. });
  281. });
  282. it('should transform jsErrors offenders', function() {
  283. results = rulesChecker.check({
  284. "toolsResults": {
  285. "phantomas": {
  286. "metrics": {
  287. "jsErrors": 2
  288. },
  289. "offenders": {
  290. "jsErrors": [
  291. "TypeError: 'undefined' is not a function (evaluating 'this.successfullyCollected.bind(this)') - http://asset.easydmp.net/js/collect.js:1160 / callCollecte http://asset.easydmp.net/js/collect.js:1203 / callbackUpdateParams http://asset.easydmp.net/js/collect.js:1135 / http://asset.easydmp.net/js/collect.js:1191",
  292. "TypeError: 'undefined' is not an object (evaluating 'd.readyState') - http://me.hunkal.com/p/:3"
  293. ]
  294. }
  295. }
  296. }
  297. }, policies);
  298. results.should.have.a.property('jsErrors');
  299. results.jsErrors.should.have.a.property('offendersObj').that.deep.equals({
  300. "count": 2,
  301. "list": [
  302. {
  303. "error": "TypeError: 'undefined' is not a function (evaluating 'this.successfullyCollected.bind(this)')",
  304. "backtrace": [
  305. {
  306. "file": "http://asset.easydmp.net/js/collect.js",
  307. "line": 1160
  308. },
  309. {
  310. "file": "http://asset.easydmp.net/js/collect.js",
  311. "line": 1203,
  312. "functionName": "callCollecte"
  313. },
  314. {
  315. "file": "http://asset.easydmp.net/js/collect.js",
  316. "line": 1135,
  317. "functionName": "callbackUpdateParams"
  318. },
  319. {
  320. "file": "http://asset.easydmp.net/js/collect.js",
  321. "line": 1191
  322. }
  323. ]
  324. },
  325. {
  326. "error": "TypeError: 'undefined' is not an object (evaluating 'd.readyState')",
  327. "backtrace": [
  328. {
  329. "file": "http://me.hunkal.com/p/",
  330. "line": 3
  331. }
  332. ]
  333. }
  334. ]
  335. });
  336. });
  337. it('should grade correctly jQuery versions', function() {
  338. var versions = {
  339. '1.2.9': 0,
  340. '1.3.9': 0,
  341. '1.4.4': 10,
  342. '1.5.0': 20,
  343. '1.6.3': 30,
  344. '1.7.0': 40,
  345. '1.8.3a': 50,
  346. '1.9.2': 70,
  347. '1.10.1': 90,
  348. '2.0.0-rc1': 90,
  349. '1.11.1': 100,
  350. '2.1.1-beta1': 100,
  351. '3.0.0': 100
  352. };
  353. for (var version in versions) {
  354. results = rulesChecker.check({
  355. "toolsResults": {
  356. "phantomas": {
  357. "metrics": {
  358. "jQueryVersion": version
  359. }
  360. }
  361. }
  362. }, policies);
  363. results.jQueryVersion.score.should.equal(versions[version]);
  364. }
  365. // Unknown jQuery version
  366. results = rulesChecker.check({
  367. "toolsResults": {
  368. "phantomas": {
  369. "metrics": {
  370. "jQueryVersion": "wooot"
  371. }
  372. }
  373. }
  374. }, policies);
  375. results.should.deep.equals({});
  376. // If jQueryVersionsLoaded is 0
  377. results = rulesChecker.check({
  378. "toolsResults": {
  379. "phantomas": {
  380. "metrics": {
  381. "jQueryVersion": "1.6.0",
  382. "jQueryVersionsLoaded": 0
  383. }
  384. }
  385. }
  386. }, policies);
  387. results.should.not.have.a.property('jQueryVersion');
  388. results.should.have.a.property('jQueryVersionsLoaded');
  389. results.jQueryVersionsLoaded.should.have.a.property('score').that.equals(100);
  390. // If there are more than 1 jQuery version
  391. results = rulesChecker.check({
  392. "toolsResults": {
  393. "phantomas": {
  394. "metrics": {
  395. "jQueryVersion": "1.6.0",
  396. "jQueryVersionsLoaded": 2
  397. }
  398. }
  399. }
  400. }, policies);
  401. results.should.not.have.a.property('jQueryVersion');
  402. results.should.have.a.property('jQueryVersionsLoaded');
  403. results.jQueryVersionsLoaded.should.have.a.property('score').that.equals(0);
  404. results.jQueryVersionsLoaded.should.have.a.property('abnormal').that.equals(true);
  405. });
  406. it('should transform cssParsingErrors offenders', function() {
  407. results = rulesChecker.check({
  408. "toolsResults": {
  409. "phantomas": {
  410. "metrics": {
  411. "cssParsingErrors": 2
  412. },
  413. "offenders": {
  414. "cssParsingErrors": [
  415. "<http://www.sudexpress.com/skin/frontend/sudexpress/default/css/styles.css> (Error: CSS parsing failed: missing '}' @ 4:1)",
  416. "<http://www.sudexpress.com/skin/frontend/sudexpress/default/css/reset.css> (Empty CSS was provided)"
  417. ]
  418. }
  419. }
  420. }
  421. }, policies);
  422. results.should.have.a.property('cssParsingErrors');
  423. results.cssParsingErrors.should.have.a.property('offendersObj').that.deep.equals({
  424. "count": 2,
  425. "list": [
  426. {
  427. "error": "Error: CSS parsing failed: missing '}'",
  428. "file": "http://www.sudexpress.com/skin/frontend/sudexpress/default/css/styles.css",
  429. "line": 4,
  430. "column": 1
  431. },
  432. {
  433. "error": "Empty CSS was provided",
  434. "file": "http://www.sudexpress.com/skin/frontend/sudexpress/default/css/reset.css",
  435. "line": null,
  436. "column": null
  437. }
  438. ]
  439. });
  440. });
  441. // Enough for the moment, to be complete...
  442. });