Skip to content

Commit 55b54d9

Browse files
authored
Set up eslint (#197)
* set up eslint * fix autofixable eslint issues * set up jsdiff; some test failures * use diffArrays; one more test passing * all tests passing! * allWhitespace * more efficient whitespace check * split up utility / diff tests * add comment * totally gut difflib * this is no longer jsdifflib * difflib -> string-utils * truly no more difflib * ESM jest config * disable eslint for webpack config * knip ignore * lint on CI * bump node version
1 parent e0afa5c commit 55b54d9

32 files changed

+751
-743
lines changed

.circleci/config.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636
3737
test-js:
3838
docker:
39-
- image: cimg/node:18.8.0
39+
- image: cimg/node:20.14
4040
steps:
4141
- checkout
4242
- run: node --version
@@ -54,6 +54,7 @@ jobs:
5454
yarn run format:check
5555
yarn run knip
5656
yarn run tsc --noEmit
57+
yarn run lint
5758
5859
workflows:
5960
main:

ts/AnnotatedImage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export function AnnotatedImage(props: Props) {
1414
return <span>None</span>;
1515
}
1616

17-
var im = props.filePair[side === 'a' ? 'image_a' : 'image_b'];
17+
const im = props.filePair[side === 'a' ? 'image_a' : 'image_b'];
1818
return (
1919
<div className={'image-' + side}>
2020
<SingleImage {...props} />

ts/CodeDiffContainer.tsx

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {DiffOptions, encodeDiffOptions} from './diff-options';
33
import {CodeDiff, PatchOptions} from './codediff/codediff';
44
import {guessLanguageUsingContents, guessLanguageUsingFileName} from './codediff/language';
55
import {GitConfig} from './options';
6+
import {DiffRange} from './codediff/codes';
67

78
interface BaseFilePair {
89
idx: number;
@@ -11,6 +12,8 @@ interface BaseFilePair {
1112
/** file name of right side of diff */
1213
b: string;
1314
type: 'add' | 'delete' | 'move' | 'change'; // XXX check "change"
15+
/** Are there any changes to the file? Only set for "thick" diffs. */
16+
no_changes?: boolean;
1417
}
1518

1619
interface TextFilePair extends BaseFilePair {
@@ -48,7 +51,7 @@ export interface ImageDiffData {
4851
}
4952

5053
// A "no changes" sign which only appears when applicable.
51-
export function NoChanges(props: {filePair: any}) {
54+
export function NoChanges(props: {filePair: FilePair}) {
5255
const {filePair} = props;
5356
if (filePair.no_changes) {
5457
return <div className="no-changes">(File content is identical)</div>;
@@ -80,7 +83,7 @@ export function CodeDiffContainer(props: {filePair: FilePair; diffOptions: Parti
8083
const {filePair, diffOptions} = props;
8184
const codediffRef = React.useRef<HTMLDivElement>(null);
8285
const [contents, setContents] = React.useState<
83-
{before: string | null; after: string | null; diffOps: any} | undefined
86+
{before: string | null; after: string | null; diffOps: DiffRange[]} | undefined
8487
>();
8588

8689
React.useEffect(() => {
@@ -137,11 +140,11 @@ interface FileDiffProps {
137140
pathAfter: string;
138141
contentsBefore: string | null;
139142
contentsAfter: string | null;
140-
diffOps: any[];
143+
diffOps: DiffRange[];
141144
}
142145

143146
function extractFilename(path: string) {
144-
var parts = path.split('/');
147+
const parts = path.split('/');
145148
return parts[parts.length - 1];
146149
}
147150
const HIGHLIGHT_BLACKLIST = ['TODO', 'README', 'NOTES'];
@@ -162,7 +165,7 @@ function FileDiff(props: FileDiffProps) {
162165
const path = pathBefore || pathAfter;
163166
let language = guessLanguageUsingFileName(path);
164167

165-
const lengthOrZero = function (data: any[] | string | null | undefined) {
168+
const lengthOrZero = function (data: unknown[] | string | null | undefined) {
166169
return data ? data.length : 0;
167170
};
168171
const lastOp = diffOps[diffOps.length - 1];
@@ -173,7 +176,7 @@ function FileDiff(props: FileDiffProps) {
173176
HIGHLIGHT_BLACKLIST.indexOf(extractFilename(path)) === -1 &&
174177
numLines < GIT_CONFIG.webdiff.maxLinesForSyntax
175178
) {
176-
var byLength = [contentsBefore, contentsAfter];
179+
let byLength = [contentsBefore, contentsAfter];
177180
if (contentsAfter && lengthOrZero(contentsAfter) > lengthOrZero(contentsBefore)) {
178181
byLength = [byLength![1], byLength![0]];
179182
}

ts/ImageDiff.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export function ImageDiff(props: Props) {
3434
};
3535

3636
let mode = props.imageDiffMode;
37-
let pair = props.filePair;
37+
const pair = props.filePair;
3838
if (isOneSided(pair)) {
3939
mode = 'side-by-side'; // Only one that makes sense for one-sided diffs.
4040
}
@@ -80,15 +80,15 @@ export function ImageDiff(props: Props) {
8080
'onion-skin': ImageOnionSkin,
8181
swipe: ImageSwipe,
8282
}[mode];
83-
var image = React.createElement(component, {
83+
const image = React.createElement(component, {
8484
filePair: pair,
8585
shrinkToFit,
8686
pdiffMode: props.pdiffMode,
8787
});
88-
var diffBoxEnabled = isSameSizeImagePair(pair);
89-
var boxClasses = diffBoxEnabled ? '' : 'diff-box-disabled';
90-
var boxStyles = {display: HAS_IMAGE_MAGICK ? '' : 'none'};
91-
var imageMagickCallout = !HAS_IMAGE_MAGICK ? (
88+
const diffBoxEnabled = isSameSizeImagePair(pair);
89+
const boxClasses = diffBoxEnabled ? '' : 'diff-box-disabled';
90+
const boxStyles = {display: HAS_IMAGE_MAGICK ? '' : 'none'};
91+
const imageMagickCallout = !HAS_IMAGE_MAGICK ? (
9292
<span className="magick">
9393
Install <a href="http://www.imagemagick.org/script/binary-releases.php">ImageMagick</a> to see
9494
perceptual diffs

ts/ImageDiffModeSelector.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ export function ImageDiffModeSelector(props: Props) {
2020
}
2121

2222
// Returns the text, optionally wrapped in a link and/or <b> tag.
23-
var linkOrB = (isLink: boolean, isB: boolean, val: ImageDiffMode, text: string) => {
24-
var inner = isB ? <b>{text}</b> : text;
23+
const linkOrB = (isLink: boolean, isB: boolean, val: ImageDiffMode, text: string) => {
24+
const inner = isB ? <b>{text}</b> : text;
2525
if (isLink) {
2626
return (
2727
<a href="#" onClick={() => props.changeImageDiffModeHandler(val)}>

ts/ImageSideBySide.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {ImageDiffProps} from './ImageDiff';
44

55
// Two images placed side-by-side.
66
export function ImageSideBySide(props: ImageDiffProps) {
7-
var maxWidth = props.shrinkToFit ? (window.innerWidth - 30) / 2 : null;
7+
const maxWidth = props.shrinkToFit ? (window.innerWidth - 30) / 2 : null;
88
return (
99
<table id="imagediff">
1010
<tbody>

ts/ImageSwipe.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export function ImageSwipe(props: ImageSwipeProps) {
3939
imB.height *= scaleDown;
4040
containerWidth = Math.max(imA.width, imB.width);
4141
}
42-
var diffBoxDiv = makePerceptualBoxDiv(props.pdiffMode, pair, scaleDown);
42+
const diffBoxDiv = makePerceptualBoxDiv(props.pdiffMode, pair, scaleDown);
4343
const urlA = '/a/image/' + pair.a;
4444
const urlB = '/b/image/' + pair.b;
4545
const styleA: React.CSSProperties = {
@@ -73,12 +73,12 @@ export function ImageSwipe(props: ImageSwipeProps) {
7373
}
7474

7575
// Add an opaque grid under each image to expose transparency.
76-
[styleA, styleB].forEach(function (o) {
77-
(o as any)['backgroundImage'] += ', url(/static/img/trans_bg.gif)';
76+
for (const o of [styleA, styleB]) {
77+
o.backgroundImage += ', url(/static/img/trans_bg.gif)';
7878
if (_.has(o, 'backgroundSize')) {
79-
(o as any)['backgroundSize'] += ', auto auto';
79+
o.backgroundSize += ', auto auto';
8080
}
81-
});
81+
}
8282

8383
return (
8484
<div>

ts/__tests__/util.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ test('util.filePairDisplayName', () => {
1818
expect(rename('dir/file.json', 'dir/renamed.json')).toEqual('dir/{file → renamed}.json');
1919
expect(rename('file.json', 'dir/file.json')).toEqual('{ → dir/}file.json');
2020
expect(rename('/foo/bar/file.json', '/foo/baz/file.json')).toEqual('/foo/{bar → baz}/file.json');
21-
expect(rename('/foo/bar/file.json', '/foo/file.json')).toEqual('/foo{/bar → }/file.json');
21+
expect(rename('/foo/bar/file.json', '/foo/file.json')).toEqual('/foo/{bar/ → }file.json');
2222

2323
// this one is controversial, maybe better not to factor out anything?
2424
expect(rename('/foo/bar/file.json', '/fox/bar/file.js')).toEqual(

ts/codediff/__tests__/addcharacterdiffs_test.ts

Lines changed: 54 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ function htmlToText(html: string) {
2121
return div.textContent ?? '';
2222
}
2323

24-
describe('add character diffs', () => {
24+
describe('utility code', () => {
2525
test('simplifyCodes', () => {
2626
const x = 'replace';
2727
const y = 'equal';
@@ -69,6 +69,50 @@ describe('add character diffs', () => {
6969
);
7070
});
7171

72+
test('splitIntoWords', () => {
73+
expect(splitIntoWords('<ImageDiffModeSelector filePair={filePair}')).toEqual([
74+
'<',
75+
'Image',
76+
'Diff',
77+
'Mode',
78+
'Selector',
79+
' ',
80+
'file',
81+
'Pair',
82+
'=',
83+
'{',
84+
'file',
85+
'Pair',
86+
'}',
87+
]);
88+
expect(splitIntoWords('<DiffView filePair={filePair}')).toEqual([
89+
'<',
90+
'Diff',
91+
'View',
92+
' ',
93+
'file',
94+
'Pair',
95+
'=',
96+
'{',
97+
'file',
98+
'Pair',
99+
'}',
100+
]);
101+
expect(splitIntoWords('Test1TEST23testAbc{}')).toEqual([
102+
'Test',
103+
'1',
104+
'TEST',
105+
'23',
106+
'test',
107+
'Abc',
108+
'{',
109+
'}',
110+
]);
111+
expect(splitIntoWords(' FooBar')).toEqual([' ', ' ', ' ', 'Foo', 'Bar']);
112+
});
113+
});
114+
115+
describe('add character diffs', () => {
72116
test('char diffs -- simple', () => {
73117
const beforeText = " return '' + date.getFullYear();";
74118
const afterText = " return 'xx' + date.getFullYear();";
@@ -109,8 +153,9 @@ describe('add character diffs', () => {
109153
});
110154

111155
test('mixed inserts and markup', () => {
112-
var beforeHtml = '<span class="hljs-string">"q"</span>, s';
113-
var afterHtml = '<span class="hljs-string">"q"</span><span class="hljs-comment">/*, s*/</span>';
156+
const beforeHtml = '<span class="hljs-string">"q"</span>, s';
157+
const afterHtml =
158+
'<span class="hljs-string">"q"</span><span class="hljs-comment">/*, s*/</span>';
114159

115160
const beforeText = htmlToText(beforeHtml);
116161
const afterText = htmlToText(afterHtml);
@@ -132,20 +177,20 @@ describe('add character diffs', () => {
132177
expect(codes).not.toBeNull();
133178
// 'Declined to generate a diff when one was expected.');
134179

135-
var beforeCodes = codes[0],
180+
const beforeCodes = codes[0],
136181
afterCodes = codes[1];
137182

138-
var process = function (codes: CharacterDiff[], txt: string) {
183+
const process = function (codes: CharacterDiff[], txt: string) {
139184
return codes
140185
.map(function (code) {
141-
var part = txt.substring(code[1], code[2]);
186+
let part = txt.substring(code[1], code[2]);
142187
if (code[0] != null) part = '[' + part + ']';
143188
return part;
144189
})
145190
.join('');
146191
};
147192

148-
var beforeActual = process(beforeCodes, beforeText),
193+
const beforeActual = process(beforeCodes, beforeText),
149194
afterActual = process(afterCodes, afterText);
150195

151196
expect(beforeActual).toEqual(beforeExpectation);
@@ -162,48 +207,6 @@ describe('add character diffs', () => {
162207
);
163208
});
164209

165-
test('splitIntoWords', () => {
166-
expect(splitIntoWords('<ImageDiffModeSelector filePair={filePair}')).toEqual([
167-
'<',
168-
'Image',
169-
'Diff',
170-
'Mode',
171-
'Selector',
172-
' ',
173-
'file',
174-
'Pair',
175-
'=',
176-
'{',
177-
'file',
178-
'Pair',
179-
'}',
180-
]);
181-
expect(splitIntoWords('<DiffView filePair={filePair}')).toEqual([
182-
'<',
183-
'Diff',
184-
'View',
185-
' ',
186-
'file',
187-
'Pair',
188-
'=',
189-
'{',
190-
'file',
191-
'Pair',
192-
'}',
193-
]);
194-
expect(splitIntoWords('Test1TEST23testAbc{}')).toEqual([
195-
'Test',
196-
'1',
197-
'TEST',
198-
'23',
199-
'test',
200-
'Abc',
201-
'{',
202-
'}',
203-
]);
204-
expect(splitIntoWords(' FooBar')).toEqual([' ', ' ', ' ', 'Foo', 'Bar']);
205-
});
206-
207210
test('char diffs on word boundaries', () => {
208211
assertCharDiff(
209212
'<ImageDiffModeSelector filePair={filePair}',
@@ -243,7 +246,7 @@ describe('add character diffs', () => {
243246

244247
assertCharDiff(
245248
'import net.sf.samtools._',
246-
'import [net.sf].samtools._',
249+
'import [net].[sf.]samtools._',
247250
'import htsjdk.samtools._',
248251
'import [htsjdk].samtools._',
249252
);
@@ -262,7 +265,7 @@ describe('add character diffs', () => {
262265
' <div className="examine-page">',
263266
' <div className="examine-page">',
264267
' <div className="examine-page">',
265-
'[ ] <div className="examine-page">',
268+
' [ ]<div className="examine-page">',
266269
);
267270

268271
assertCharDiff('foobar', 'foobar', ' foobar', '[ ]foobar');

ts/codediff/__tests__/diffranges_test.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
import {addSkips} from '../codes';
2-
import {OpCode} from '../difflib';
1+
import {addSkips, OpCode} from '../codes';
32

43
test('generates same diff ranges as jsdifflib', () => {
54
// These are the opcodes for test.html
6-
var opcodes: OpCode[] = [
5+
const opcodes: OpCode[] = [
76
['equal', 0, 9, 0, 9],
87
['replace', 9, 11, 9, 11],
98
['equal', 11, 14, 11, 14],
@@ -17,7 +16,7 @@ test('generates same diff ranges as jsdifflib', () => {
1716
['equal', 32, 43, 30, 41],
1817
];
1918

20-
var ranges = addSkips(opcodes, 3, 0);
19+
let ranges = addSkips(opcodes, 3, 0);
2120
expect(ranges).toEqual([
2221
{type: 'skip', before: [0, 6], after: [0, 6]},
2322
{type: 'equal', before: [6, 9], after: [6, 9]},
@@ -36,7 +35,7 @@ test('generates same diff ranges as jsdifflib', () => {
3635
{type: 'skip', before: [35, 43], after: [33, 41]},
3736
]);
3837

39-
var ranges = addSkips(opcodes, 3, 5); // minJumpSize = 5
38+
ranges = addSkips(opcodes, 3, 5); // minJumpSize = 5
4039
expect(ranges).toEqual([
4140
{type: 'skip', before: [0, 6], after: [0, 6]},
4241
{type: 'equal', before: [6, 9], after: [6, 9]},
@@ -53,7 +52,7 @@ test('generates same diff ranges as jsdifflib', () => {
5352
{type: 'skip', before: [35, 43], after: [33, 41]},
5453
]);
5554

56-
var ranges = addSkips(opcodes, 3, 10); // minJumpSize = 10
55+
ranges = addSkips(opcodes, 3, 10); // minJumpSize = 10
5756
expect(ranges).toEqual([
5857
{type: 'equal', before: [0, 9], after: [0, 9]}, // was skip
5958
{type: 'replace', before: [9, 11], after: [9, 11]},

0 commit comments

Comments
 (0)