Skip to content
This repository was archived by the owner on Mar 23, 2024. It is now read-only.

Commit 6e1e3b9

Browse files
committed
Full JsFile coverage
1 parent ff142d9 commit 6e1e3b9

File tree

2 files changed

+192
-20
lines changed

2 files changed

+192
-20
lines changed

lib/js-file.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,9 @@ var JsFile = function(filename, source, tree) {
5353
// Part of temporary esprima fix.
5454
function convertKeywordToIdentifierIfRequired(node) {
5555
var tokenPos = _this.getTokenPosByRangeStart(node.range[0]);
56-
if (tokenPos !== undefined) {
57-
var token = _this._tree.tokens[tokenPos];
58-
if (token.type === 'Keyword') {
59-
token.type = 'Identifier';
60-
}
56+
var token = _this._tree.tokens[tokenPos];
57+
if (token.type === 'Keyword') {
58+
token.type = 'Identifier';
6159
}
6260
}
6361
};
@@ -274,7 +272,7 @@ JsFile.prototype = {
274272
* Calls passed function for every token.
275273
*
276274
* @param {Function} cb
277-
* @param {Function} [tree]
275+
* @param {Object} [tree]
278276
*/
279277
iterate: function(cb, tree) {
280278
return treeIterator.iterate(tree || this._tree, cb);

test/js-file.js

Lines changed: 188 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ describe('modules/js-file', function() {
2525
describe('constructor', function() {
2626

2727
it('should accept empty token tree', function() {
28-
var file = new JsFile(null, 'Hello\nWorld', null);
28+
var file = new JsFile('example.js', 'Hello\nWorld', null);
2929
assert(Array.isArray(file.getTokens()));
3030
assert.equal(file.getTokens().length, 0);
3131
});
@@ -38,7 +38,7 @@ describe('modules/js-file', function() {
3838
'break: true, export: true, return: true, case: true, for: true, switch: true, comment: true,' +
3939
'function: true, this: true, continue: true, if: true, typeof: true, default: true, import: true,' +
4040
'var: true, delete: true, in: true, void: true, do: true, label: true, while: true, else: true,' +
41-
'new: true, with: true, catch: true, try: true, finally: true' +
41+
'new: true, with: true, catch: true, try: true, finally: true, \'\': true, null: true, 0: true' +
4242
'})';
4343
createJsFile(str).getTokens().forEach(function(token) {
4444
assert(token.type !== 'Keyword');
@@ -458,8 +458,7 @@ describe('modules/js-file', function() {
458458

459459
describe('getTokenByRangeStart', function() {
460460
it('should return token for specified start position', function() {
461-
var str = 'if (true) { x++; }';
462-
var file = new JsFile(null, str, esprima.parse(str, {loc: true, range: true, tokens: true}));
461+
var file = createJsFile('if (true) { x++; }');
463462

464463
var ifToken = file.getTokenByRangeStart(0);
465464
assert.equal(ifToken.type, 'Keyword');
@@ -471,8 +470,7 @@ describe('modules/js-file', function() {
471470
});
472471

473472
it('should return undefined if token was not found', function() {
474-
var str = 'if (true) { x++; }';
475-
var file = new JsFile(null, str, esprima.parse(str, {loc: true, range: true, tokens: true}));
473+
var file = createJsFile('if (true) { x++; }');
476474

477475
var token = file.getTokenByRangeStart(1);
478476
assert(token === undefined);
@@ -481,8 +479,7 @@ describe('modules/js-file', function() {
481479

482480
describe('getTokenByRangeEnd', function() {
483481
it('should return token for specified end position', function() {
484-
var str = 'if (true) { x++; }';
485-
var file = new JsFile(null, str, esprima.parse(str, {loc: true, range: true, tokens: true}));
482+
var file = createJsFile('if (true) { x++; }');
486483

487484
var ifToken = file.getTokenByRangeEnd(2);
488485
assert.equal(ifToken.type, 'Keyword');
@@ -494,8 +491,7 @@ describe('modules/js-file', function() {
494491
});
495492

496493
it('should return undefined if token was not found', function() {
497-
var str = 'if (true) { x++; }';
498-
var file = new JsFile(null, str, esprima.parse(str, {loc: true, range: true, tokens: true}));
494+
var file = createJsFile('if (true) { x++; }');
499495

500496
var token = file.getTokenByRangeEnd(3);
501497
assert(token === undefined);
@@ -504,8 +500,7 @@ describe('modules/js-file', function() {
504500

505501
describe('getFirstNodeToken', function() {
506502
it('should return token for specified node', function() {
507-
var str = 'if (true) { while (true) x++; }';
508-
var file = new JsFile(null, str, esprima.parse(str, {loc: true, range: true, tokens: true}));
503+
var file = createJsFile('if (true) { while (true) x++; }');
509504

510505
var ifToken = file.getFirstNodeToken(file.getNodesByType('IfStatement')[0]);
511506
assert.equal(ifToken.type, 'Keyword');
@@ -519,8 +514,7 @@ describe('modules/js-file', function() {
519514

520515
describe('getLastNodeToken', function() {
521516
it('should return token for specified node', function() {
522-
var str = 'if (true) { while (true) x++; }';
523-
var file = new JsFile(null, str, esprima.parse(str, {loc: true, range: true, tokens: true}));
517+
var file = createJsFile('if (true) { while (true) x++; }');
524518

525519
var ifToken = file.getLastNodeToken(file.getNodesByType('IfStatement')[0]);
526520
assert.equal(ifToken.type, 'Punctuator');
@@ -531,4 +525,184 @@ describe('modules/js-file', function() {
531525
assert.equal(incToken.value, '++');
532526
});
533527
});
528+
529+
describe('getNodesByType', function() {
530+
it('should return nodes using specified type', function() {
531+
var nodes = createJsFile('x++;y++;').getNodesByType('Identifier');
532+
assert.equal(nodes.length, 2);
533+
assert.equal(nodes[0].type, 'Identifier');
534+
assert.equal(nodes[0].name, 'x');
535+
assert.equal(nodes[1].type, 'Identifier');
536+
assert.equal(nodes[1].name, 'y');
537+
});
538+
539+
it('should return empty array for non-existing type', function() {
540+
var nodes = createJsFile('x++;y++;').getNodesByType('Literal');
541+
assert.equal(nodes.length, 0);
542+
});
543+
544+
it('should accept array as an argument', function() {
545+
var nodes = createJsFile('x += 1;').getNodesByType(['Identifier', 'Literal']);
546+
assert.equal(nodes.length, 2);
547+
assert.equal(nodes[0].type, 'Identifier');
548+
assert.equal(nodes[0].name, 'x');
549+
assert.equal(nodes[1].type, 'Literal');
550+
assert.equal(nodes[1].value, 1);
551+
});
552+
553+
it('should return empty array for non-existing type array', function() {
554+
var nodes = createJsFile('x++;y++;').getNodesByType(['Literal', 'BinaryExpression']);
555+
assert.equal(nodes.length, 0);
556+
});
557+
});
558+
559+
describe('iterate', function() {
560+
it('should iterate all nodes in the document', function() {
561+
var file = createJsFile('x++;');
562+
563+
var spy = sinon.spy();
564+
file.iterate(spy);
565+
566+
assert.equal(spy.callCount, 4);
567+
568+
assert.equal(spy.getCall(0).args[0].type, 'Program');
569+
assert.equal(spy.getCall(1).args[0].type, 'ExpressionStatement');
570+
assert.equal(spy.getCall(2).args[0].type, 'UpdateExpression');
571+
assert.equal(spy.getCall(3).args[0].type, 'Identifier');
572+
});
573+
574+
it('should iterate nested nodes', function() {
575+
var file = createJsFile('x = (5 + 4) && (3 + 1);');
576+
577+
var spy = sinon.spy();
578+
file.iterate(spy, file.getNodesByType('LogicalExpression')[0].left);
579+
580+
assert.equal(spy.callCount, 3);
581+
assert.equal(spy.getCall(0).args[0].type, 'BinaryExpression');
582+
assert.equal(spy.getCall(1).args[0].type, 'Literal');
583+
assert.equal(spy.getCall(1).args[0].value, 5);
584+
assert.equal(spy.getCall(2).args[0].type, 'Literal');
585+
assert.equal(spy.getCall(2).args[0].value, 4);
586+
});
587+
});
588+
589+
describe('iterateNodesByType', function() {
590+
it('should apply callback using specified type', function() {
591+
var spy = sinon.spy();
592+
createJsFile('x++;y++;').iterateNodesByType('Identifier', spy);
593+
assert.equal(spy.callCount, 2);
594+
assert.equal(spy.getCall(0).args[0].type, 'Identifier');
595+
assert.equal(spy.getCall(0).args[0].name, 'x');
596+
assert.equal(spy.getCall(1).args[0].type, 'Identifier');
597+
assert.equal(spy.getCall(1).args[0].name, 'y');
598+
});
599+
600+
it('should not apply callback for non-existing type', function() {
601+
var spy = sinon.spy();
602+
createJsFile('x++;y++;').iterateNodesByType('Literal', spy);
603+
assert(!spy.called);
604+
});
605+
606+
it('should accept array as an argument', function() {
607+
var spy = sinon.spy();
608+
createJsFile('x += 1;').iterateNodesByType(['Identifier', 'Literal'], spy);
609+
assert.equal(spy.callCount, 2);
610+
assert.equal(spy.getCall(0).args[0].type, 'Identifier');
611+
assert.equal(spy.getCall(0).args[0].name, 'x');
612+
assert.equal(spy.getCall(1).args[0].type, 'Literal');
613+
assert.equal(spy.getCall(1).args[0].value, 1);
614+
});
615+
616+
it('should not apply callback for non-existing type array', function() {
617+
var spy = sinon.spy();
618+
createJsFile('x++;y++;').iterateNodesByType(['Literal', 'BinaryExpression'], spy);
619+
assert(!spy.called);
620+
});
621+
});
622+
623+
describe('iterateTokensByType', function() {
624+
it('should apply callback using specified type', function() {
625+
var spy = sinon.spy();
626+
createJsFile('x++;y++;').iterateTokensByType('Identifier', spy);
627+
assert.equal(spy.callCount, 2);
628+
assert.equal(spy.getCall(0).args[0].type, 'Identifier');
629+
assert.equal(spy.getCall(0).args[0].value, 'x');
630+
assert.equal(spy.getCall(1).args[0].type, 'Identifier');
631+
assert.equal(spy.getCall(1).args[0].value, 'y');
632+
});
633+
634+
it('should not apply callback for non-existing type', function() {
635+
var spy = sinon.spy();
636+
createJsFile('x++;y++;').iterateTokensByType('Boolean', spy);
637+
assert(!spy.called);
638+
});
639+
640+
it('should accept array as an argument', function() {
641+
var spy = sinon.spy();
642+
createJsFile('x += 1;').iterateTokensByType(['Identifier', 'Numeric'], spy);
643+
assert.equal(spy.callCount, 2);
644+
assert.equal(spy.getCall(0).args[0].type, 'Identifier');
645+
assert.equal(spy.getCall(0).args[0].value, 'x');
646+
assert.equal(spy.getCall(1).args[0].type, 'Numeric');
647+
assert.equal(spy.getCall(1).args[0].value, '1');
648+
});
649+
650+
it('should not apply callback for non-existing type array', function() {
651+
var spy = sinon.spy();
652+
createJsFile('x++;y++;').iterateTokensByType(['Boolean', 'Numeric'], spy);
653+
assert(!spy.called);
654+
});
655+
});
656+
657+
describe('getTree', function() {
658+
it('should return specified esprima-tree', function() {
659+
var sources = 'var x;';
660+
var tree = esprima.parse(sources, {loc: true, range: true, comment: true, tokens: true});
661+
var file = new JsFile('example.js', sources, tree);
662+
assert.equal(file.getTree(), tree);
663+
});
664+
665+
it('should return empty token tree for non-existing esprima-tree', function() {
666+
var file = new JsFile('example.js', 'Hello\nWorld', null);
667+
assert.equal(typeof file.getTree(), 'object');
668+
assert(file.getTree() !== null);
669+
});
670+
});
671+
672+
describe('getSource', function() {
673+
it('should return specified source code', function() {
674+
var sources = 'var x = 1;\nvar y = 2;';
675+
var file = createJsFile(sources);
676+
assert.equal(file.getSource(), sources);
677+
});
678+
});
679+
680+
describe('getLines', function() {
681+
it('should return specified source code lines', function() {
682+
var sources = ['var x = 1;', 'var y = 2;'];
683+
var file = createJsFile(sources.join('\n'));
684+
assert.equal(file.getLines().length, 2);
685+
assert.equal(file.getLines()[0], sources[0]);
686+
assert.equal(file.getLines()[1], sources[1]);
687+
});
688+
689+
it('should accept all line endings', function() {
690+
var lineEndings = ['\r\n', '\r', '\n'];
691+
692+
lineEndings.forEach(function(lineEnding) {
693+
var sources = ['var x = 1;', 'var y = 2;'];
694+
var file = createJsFile(sources.join(lineEnding));
695+
assert.equal(file.getLines().length, 2);
696+
assert.equal(file.getLines()[0], sources[0]);
697+
assert.equal(file.getLines()[1], sources[1]);
698+
});
699+
});
700+
});
701+
702+
describe('getFilename', function() {
703+
it('should return given filename', function() {
704+
var file = new JsFile('example.js', 'Hello\nWorld', null);
705+
assert.equal(file.getFilename(), 'example.js');
706+
});
707+
});
534708
});

0 commit comments

Comments
 (0)