2018-12-13 13:39:08 +05:30
|
|
|
/* eslint-disable no-var, prefer-template, no-else-return, dot-notation, no-return-assign, no-new, no-underscore-dangle */
|
2016-09-13 17:45:13 +05:30
|
|
|
|
2018-05-09 12:01:36 +05:30
|
|
|
import $ from 'jquery';
|
2018-03-17 18:26:18 +05:30
|
|
|
import LineHighlighter from '~/line_highlighter';
|
2016-09-13 17:45:13 +05:30
|
|
|
|
2018-12-13 13:39:08 +05:30
|
|
|
describe('LineHighlighter', function() {
|
|
|
|
var clickLine;
|
2019-05-18 00:54:41 +05:30
|
|
|
preloadFixtures('static/line_highlighter.html');
|
2018-12-13 13:39:08 +05:30
|
|
|
clickLine = function(number, eventData = {}) {
|
|
|
|
if ($.isEmptyObject(eventData)) {
|
|
|
|
return $('#L' + number).click();
|
|
|
|
} else {
|
|
|
|
const e = $.Event('click', eventData);
|
|
|
|
return $('#L' + number).trigger(e);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
beforeEach(function() {
|
2019-05-18 00:54:41 +05:30
|
|
|
loadFixtures('static/line_highlighter.html');
|
2018-12-13 13:39:08 +05:30
|
|
|
this['class'] = new LineHighlighter();
|
|
|
|
this.css = this['class'].highlightLineClass;
|
|
|
|
return (this.spies = {
|
|
|
|
__setLocationHash__: spyOn(this['class'], '__setLocationHash__').and.callFake(function() {}),
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('behavior', function() {
|
|
|
|
it('highlights one line given in the URL hash', function() {
|
|
|
|
new LineHighlighter({ hash: '#L13' });
|
|
|
|
|
|
|
|
expect($('#LC13')).toHaveClass(this.css);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('highlights one line given in the URL hash with given CSS class name', function() {
|
|
|
|
const hiliter = new LineHighlighter({ hash: '#L13', highlightLineClass: 'hilite' });
|
|
|
|
|
|
|
|
expect(hiliter.highlightLineClass).toBe('hilite');
|
|
|
|
expect($('#LC13')).toHaveClass('hilite');
|
|
|
|
expect($('#LC13')).not.toHaveClass('hll');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('highlights a range of lines given in the URL hash', function() {
|
|
|
|
var line;
|
|
|
|
new LineHighlighter({ hash: '#L5-25' });
|
|
|
|
|
|
|
|
expect($('.' + this.css).length).toBe(21);
|
|
|
|
for (line = 5; line <= 25; line += 1) {
|
|
|
|
expect($('#LC' + line)).toHaveClass(this.css);
|
2016-09-13 17:45:13 +05:30
|
|
|
}
|
2018-12-13 13:39:08 +05:30
|
|
|
});
|
|
|
|
|
|
|
|
it('scrolls to the first highlighted line on initial load', function() {
|
|
|
|
var spy;
|
|
|
|
spy = spyOn($, 'scrollTo');
|
|
|
|
new LineHighlighter({ hash: '#L5-25' });
|
|
|
|
|
|
|
|
expect(spy).toHaveBeenCalledWith('#L5', jasmine.anything());
|
|
|
|
});
|
|
|
|
|
|
|
|
it('discards click events', function() {
|
|
|
|
var spy;
|
|
|
|
spy = spyOnEvent('a[data-line-number]', 'click');
|
|
|
|
clickLine(13);
|
|
|
|
|
|
|
|
expect(spy).toHaveBeenPrevented();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('handles garbage input from the hash', function() {
|
|
|
|
var func;
|
|
|
|
func = function() {
|
|
|
|
return new LineHighlighter({ fileHolderSelector: '#blob-content-holder' });
|
2016-09-13 17:45:13 +05:30
|
|
|
};
|
2018-12-13 13:39:08 +05:30
|
|
|
|
|
|
|
expect(func).not.toThrow();
|
2016-09-13 17:45:13 +05:30
|
|
|
});
|
2018-12-13 13:39:08 +05:30
|
|
|
});
|
|
|
|
|
|
|
|
describe('clickHandler', function() {
|
|
|
|
it('handles clicking on a child icon element', function() {
|
|
|
|
var spy;
|
|
|
|
spy = spyOn(this['class'], 'setHash').and.callThrough();
|
|
|
|
$('#L13 i')
|
|
|
|
.mousedown()
|
|
|
|
.click();
|
|
|
|
|
|
|
|
expect(spy).toHaveBeenCalledWith(13);
|
|
|
|
expect($('#LC13')).toHaveClass(this.css);
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('without shiftKey', function() {
|
|
|
|
it('highlights one line when clicked', function() {
|
|
|
|
clickLine(13);
|
|
|
|
|
|
|
|
expect($('#LC13')).toHaveClass(this.css);
|
2016-09-13 17:45:13 +05:30
|
|
|
});
|
2018-12-13 13:39:08 +05:30
|
|
|
|
|
|
|
it('unhighlights previously highlighted lines', function() {
|
|
|
|
clickLine(13);
|
|
|
|
clickLine(20);
|
|
|
|
|
|
|
|
expect($('#LC13')).not.toHaveClass(this.css);
|
|
|
|
expect($('#LC20')).toHaveClass(this.css);
|
2016-09-13 17:45:13 +05:30
|
|
|
});
|
2018-12-13 13:39:08 +05:30
|
|
|
|
|
|
|
it('sets the hash', function() {
|
2016-09-13 17:45:13 +05:30
|
|
|
var spy;
|
2018-12-13 13:39:08 +05:30
|
|
|
spy = spyOn(this['class'], 'setHash').and.callThrough();
|
2016-09-13 17:45:13 +05:30
|
|
|
clickLine(13);
|
2018-12-13 13:39:08 +05:30
|
|
|
|
|
|
|
expect(spy).toHaveBeenCalledWith(13);
|
2016-09-13 17:45:13 +05:30
|
|
|
});
|
|
|
|
});
|
2018-12-13 13:39:08 +05:30
|
|
|
|
|
|
|
describe('with shiftKey', function() {
|
|
|
|
it('sets the hash', function() {
|
2016-09-13 17:45:13 +05:30
|
|
|
var spy;
|
2018-12-13 13:39:08 +05:30
|
|
|
spy = spyOn(this['class'], 'setHash').and.callThrough();
|
|
|
|
clickLine(13);
|
|
|
|
clickLine(20, {
|
|
|
|
shiftKey: true,
|
|
|
|
});
|
|
|
|
|
2016-09-13 17:45:13 +05:30
|
|
|
expect(spy).toHaveBeenCalledWith(13);
|
2018-12-13 13:39:08 +05:30
|
|
|
expect(spy).toHaveBeenCalledWith(13, 20);
|
2016-09-13 17:45:13 +05:30
|
|
|
});
|
2018-12-13 13:39:08 +05:30
|
|
|
|
|
|
|
describe('without existing highlight', function() {
|
|
|
|
it('highlights the clicked line', function() {
|
|
|
|
clickLine(13, {
|
|
|
|
shiftKey: true,
|
|
|
|
});
|
|
|
|
|
|
|
|
expect($('#LC13')).toHaveClass(this.css);
|
|
|
|
expect($('.' + this.css).length).toBe(1);
|
2016-09-13 17:45:13 +05:30
|
|
|
});
|
2018-12-13 13:39:08 +05:30
|
|
|
|
2016-09-13 17:45:13 +05:30
|
|
|
it('sets the hash', function() {
|
|
|
|
var spy;
|
2018-12-13 13:39:08 +05:30
|
|
|
spy = spyOn(this['class'], 'setHash');
|
|
|
|
clickLine(13, {
|
|
|
|
shiftKey: true,
|
2016-09-13 17:45:13 +05:30
|
|
|
});
|
2018-12-13 13:39:08 +05:30
|
|
|
|
2016-09-13 17:45:13 +05:30
|
|
|
expect(spy).toHaveBeenCalledWith(13);
|
|
|
|
});
|
2018-12-13 13:39:08 +05:30
|
|
|
});
|
|
|
|
|
|
|
|
describe('with existing single-line highlight', function() {
|
|
|
|
it('uses existing line as last line when target is lesser', function() {
|
|
|
|
var line;
|
|
|
|
clickLine(20);
|
|
|
|
clickLine(15, {
|
|
|
|
shiftKey: true,
|
2016-09-13 17:45:13 +05:30
|
|
|
});
|
2018-12-13 13:39:08 +05:30
|
|
|
|
|
|
|
expect($('.' + this.css).length).toBe(6);
|
|
|
|
for (line = 15; line <= 20; line += 1) {
|
|
|
|
expect($('#LC' + line)).toHaveClass(this.css);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
it('uses existing line as first line when target is greater', function() {
|
|
|
|
var line;
|
|
|
|
clickLine(5);
|
|
|
|
clickLine(10, {
|
|
|
|
shiftKey: true,
|
2016-09-13 17:45:13 +05:30
|
|
|
});
|
2018-12-13 13:39:08 +05:30
|
|
|
|
|
|
|
expect($('.' + this.css).length).toBe(6);
|
|
|
|
for (line = 5; line <= 10; line += 1) {
|
|
|
|
expect($('#LC' + line)).toHaveClass(this.css);
|
|
|
|
}
|
2016-09-13 17:45:13 +05:30
|
|
|
});
|
2018-12-13 13:39:08 +05:30
|
|
|
});
|
|
|
|
|
|
|
|
describe('with existing multi-line highlight', function() {
|
|
|
|
beforeEach(function() {
|
|
|
|
clickLine(10, {
|
|
|
|
shiftKey: true,
|
2016-09-13 17:45:13 +05:30
|
|
|
});
|
2018-12-13 13:39:08 +05:30
|
|
|
clickLine(13, {
|
|
|
|
shiftKey: true,
|
2016-09-13 17:45:13 +05:30
|
|
|
});
|
|
|
|
});
|
2018-12-13 13:39:08 +05:30
|
|
|
|
|
|
|
it('uses target as first line when it is less than existing first line', function() {
|
|
|
|
var line;
|
|
|
|
clickLine(5, {
|
|
|
|
shiftKey: true,
|
2016-09-13 17:45:13 +05:30
|
|
|
});
|
2018-12-13 13:39:08 +05:30
|
|
|
|
|
|
|
expect($('.' + this.css).length).toBe(6);
|
|
|
|
for (line = 5; line <= 10; line += 1) {
|
|
|
|
expect($('#LC' + line)).toHaveClass(this.css);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
it('uses target as last line when it is greater than existing first line', function() {
|
|
|
|
var line;
|
|
|
|
clickLine(15, {
|
|
|
|
shiftKey: true,
|
2016-09-13 17:45:13 +05:30
|
|
|
});
|
2018-12-13 13:39:08 +05:30
|
|
|
|
|
|
|
expect($('.' + this.css).length).toBe(6);
|
|
|
|
for (line = 10; line <= 15; line += 1) {
|
|
|
|
expect($('#LC' + line)).toHaveClass(this.css);
|
|
|
|
}
|
2016-09-13 17:45:13 +05:30
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2018-12-13 13:39:08 +05:30
|
|
|
});
|
|
|
|
|
|
|
|
describe('hashToRange', function() {
|
|
|
|
beforeEach(function() {
|
|
|
|
this.subject = this['class'].hashToRange;
|
2016-09-13 17:45:13 +05:30
|
|
|
});
|
2018-12-13 13:39:08 +05:30
|
|
|
|
|
|
|
it('extracts a single line number from the hash', function() {
|
|
|
|
expect(this.subject('#L5')).toEqual([5, null]);
|
2016-09-13 17:45:13 +05:30
|
|
|
});
|
2018-12-13 13:39:08 +05:30
|
|
|
|
|
|
|
it('extracts a range of line numbers from the hash', function() {
|
|
|
|
expect(this.subject('#L5-15')).toEqual([5, 15]);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('returns [null, null] when the hash is not a line number', function() {
|
|
|
|
expect(this.subject('#foo')).toEqual([null, null]);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('highlightLine', function() {
|
|
|
|
beforeEach(function() {
|
|
|
|
this.subject = this['class'].highlightLine;
|
|
|
|
});
|
|
|
|
|
|
|
|
it('highlights the specified line', function() {
|
|
|
|
this.subject(13);
|
|
|
|
|
|
|
|
expect($('#LC13')).toHaveClass(this.css);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('accepts a String-based number', function() {
|
|
|
|
this.subject('13');
|
|
|
|
|
|
|
|
expect($('#LC13')).toHaveClass(this.css);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('setHash', function() {
|
|
|
|
beforeEach(function() {
|
|
|
|
this.subject = this['class'].setHash;
|
|
|
|
});
|
|
|
|
|
|
|
|
it('sets the location hash for a single line', function() {
|
|
|
|
this.subject(5);
|
|
|
|
|
|
|
|
expect(this.spies.__setLocationHash__).toHaveBeenCalledWith('#L5');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('sets the location hash for a range', function() {
|
|
|
|
this.subject(5, 15);
|
|
|
|
|
|
|
|
expect(this.spies.__setLocationHash__).toHaveBeenCalledWith('#L5-15');
|
2016-09-13 17:45:13 +05:30
|
|
|
});
|
|
|
|
});
|
2018-12-13 13:39:08 +05:30
|
|
|
});
|