Home Reference Source Test

spec/inspectorSpec.js

  1. var expect = require('expect.js');
  2. var EventEmitter = require('events').EventEmitter;
  3. var Inspector = require('../lib/inspector');
  4. var fixtures = require('./fixtures');
  5.  
  6. describe('Inspector', function() {
  7. // Used to test emitted events
  8. var found;
  9. var listener = function(match) {
  10. found.push(match);
  11. };
  12.  
  13. beforeEach(function() {
  14. found = [];
  15. });
  16.  
  17. describe('constructor', function() {
  18. it('inherits from EventEmitter', function() {
  19. expect(new Inspector()).to.be.an(EventEmitter);
  20. });
  21.  
  22. it('accepts an array of file paths', function() {
  23. var filePaths = ['path1.js', 'path2.js'];
  24. var inspector = new Inspector(filePaths);
  25. expect(inspector._filePaths).to.be(filePaths);
  26. });
  27.  
  28. it('assigns a default threshold of 30', function() {
  29. var inspector = new Inspector([]);
  30. expect(inspector._threshold).to.be(30);
  31. });
  32.  
  33. it('accepts an options object', function() {
  34. var opts = {threshold: 12};
  35. var inspector = new Inspector([], opts);
  36. expect(inspector._threshold).to.be(opts.threshold);
  37. });
  38. });
  39.  
  40. describe('run', function() {
  41. it('emits a start event', function() {
  42. var emitted;
  43. var inspector = new Inspector([fixtures.intersection]);
  44. inspector.on('start', function() {
  45. emitted = true;
  46. });
  47.  
  48. inspector.run();
  49. expect(emitted).to.be(true);
  50. });
  51.  
  52. it('emits an end event', function() {
  53. var emitted;
  54. var inspector = new Inspector([fixtures.intersection]);
  55. inspector.on('end', function() {
  56. emitted = true;
  57. });
  58.  
  59. inspector.run();
  60. expect(emitted).to.be(true);
  61. });
  62.  
  63. it('emits the "match" event when a match is found', function() {
  64. var inspector = new Inspector([fixtures.intersection], {
  65. threshold: 10
  66. });
  67.  
  68. inspector.on('match', listener);
  69. inspector.run();
  70. expect(found).to.have.length(1);
  71. });
  72. });
  73.  
  74. it('can find an exact match between instances', function() {
  75. var inspector = new Inspector([fixtures.intersection], {
  76. threshold: 15
  77. });
  78.  
  79. inspector.on('match', listener);
  80. inspector.run();
  81.  
  82. var match = found[0];
  83. expect(found).to.have.length(1);
  84. expect(match.instances).to.have.length(2);
  85. expect(match.instances[0].start).to.eql({line: 1, column: 0});
  86. expect(match.instances[0].end).to.eql({line: 5, column: 1});
  87. expect(match.instances[1].start).to.eql({line: 7, column: 0});
  88. expect(match.instances[1].end).to.eql({line: 11, column: 1});
  89. });
  90.  
  91. it('can find the largest match between two instances', function() {
  92. var inspector = new Inspector([fixtures.redundantIntersection], {
  93. threshold: 11
  94. });
  95.  
  96. inspector.on('match', listener);
  97. inspector.run();
  98.  
  99. var match = found[0];
  100. expect(found).to.have.length(1);
  101. expect(match.instances).to.have.length(2);
  102. expect(match.instances[0].start).to.eql({line: 1, column: 0});
  103. expect(match.instances[0].end).to.eql({line: 9, column: 1});
  104. expect(match.instances[1].start).to.eql({line: 11, column: 0});
  105. expect(match.instances[1].end).to.eql({line: 19, column: 1});
  106. });
  107.  
  108. it('supports ES6', function() {
  109. var inspector = new Inspector([fixtures.es6ClassExport], {
  110. threshold: 20
  111. });
  112.  
  113. inspector.on('match', listener);
  114. inspector.run();
  115.  
  116. var match = found[0];
  117. expect(found).to.have.length(1);
  118. expect(match.instances).to.have.length(2);
  119. expect(match.instances[0].start).to.eql({line: 2, column: 2});
  120. expect(match.instances[0].end).to.eql({line: 6, column: 3});
  121. expect(match.instances[1].start).to.eql({line: 8, column: 2});
  122. expect(match.instances[1].end).to.eql({line: 12, column: 3});
  123. });
  124.  
  125. it('supports JSX', function() {
  126. var inspector = new Inspector([fixtures.jsxTodo], {
  127. threshold: 20
  128. });
  129.  
  130. inspector.on('match', listener);
  131. inspector.run();
  132.  
  133. var match = found[0];
  134. expect(found).to.have.length(1);
  135. expect(match.instances).to.have.length(2);
  136. expect(match.instances[0].start).to.eql({line: 3, column: 0});
  137. expect(match.instances[0].end).to.eql({line: 9, column: 1});
  138. expect(match.instances[1].start).to.eql({line: 11, column: 0});
  139. expect(match.instances[1].end).to.eql({line: 17, column: 1});
  140. });
  141.  
  142. it('supports Flow', function() {
  143. var inspector = new Inspector([fixtures.flowIntersection], {
  144. threshold: 20
  145. });
  146.  
  147. inspector.on('match', listener);
  148. inspector.run();
  149.  
  150. var match = found[0];
  151. expect(found).to.have.length(1);
  152. expect(match.instances).to.have.length(2);
  153. expect(match.instances[0].start).to.eql({line: 1, column: 0});
  154. expect(match.instances[0].end).to.eql({line: 5, column: 1});
  155. expect(match.instances[1].start).to.eql({line: 7, column: 0});
  156. expect(match.instances[1].end).to.eql({line: 11, column: 1});
  157. });
  158.  
  159. it('includes the lines with the match', function() {
  160. var inspector = new Inspector([fixtures.intersection], {
  161. threshold: 11,
  162. });
  163.  
  164. inspector.on('match', listener);
  165. inspector.run();
  166.  
  167. var match = found[0];
  168. expect(found).to.have.length(1);
  169. expect(match.instances).to.have.length(2);
  170. expect(match.instances[0].lines).to.be(
  171. 'function intersectionA(array1, array2) {\n' +
  172. ' array1.filter(function(n) {\n' +
  173. ' return array2.indexOf(n) != -1;\n' +
  174. ' });\n' +
  175. '}'
  176. );
  177. expect(match.instances[1].lines).to.be(
  178. 'function intersectionB(arrayA, arrayB) {\n' +
  179. ' arrayA.filter(function(n) {\n' +
  180. ' return arrayB.indexOf(n) != -1;\n' +
  181. ' });\n' +
  182. '}'
  183. );
  184. });
  185.  
  186. it('ignores matches with less than the supplied minimum', function() {
  187. var inspector = new Inspector([fixtures.matches], {
  188. threshold: 2,
  189. minInstances: 3
  190. });
  191.  
  192. inspector.on('match', listener);
  193. inspector.run();
  194. expect(found).to.have.length(1);
  195. expect(found[0].instances).to.have.length(3);
  196. });
  197.  
  198. it('ignores CommonJS require statements', function() {
  199. var inspector = new Inspector([fixtures.commonjs], {
  200. threshold: 3
  201. });
  202.  
  203. inspector.on('match', listener);
  204. inspector.run();
  205. expect(found).to.have.length(0);
  206. });
  207.  
  208. it('ignores AMD define expressions', function() {
  209. var inspector = new Inspector([fixtures.amd], {
  210. threshold: 5
  211. });
  212.  
  213. inspector.on('match', listener);
  214. inspector.run();
  215. expect(found).to.have.length(0);
  216. });
  217. });