Skip to content

Commit 4d34350

Browse files
committed
more test cases
1 parent 498dc81 commit 4d34350

File tree

3 files changed

+228
-73
lines changed

3 files changed

+228
-73
lines changed

injected/scripts/utils/build.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export async function bundle(params) {
5050
'import.meta.injectName': JSON.stringify(platform),
5151
'import.meta.trackerLookup': trackerLookup,
5252
},
53-
plugins: [loadFeaturesPlugin, commentPlugin({ pathMatch: 'seedrandom/lib/alea', regex: /^\/\/ Copyright \(C\)/ })],
53+
plugins: [loadFeaturesPlugin, commentPlugin()],
5454
banner: {
5555
js: prefixMessage,
5656
},
Lines changed: 48 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,20 @@
1-
import { join } from 'path';
21
import { promises } from 'node:fs';
32

43
/**
5-
* @param {object} params
6-
* @param {string} params.pathMatch
7-
* @param {RegExp} params.regex
84
* @returns {import("esbuild").Plugin}
95
*/
10-
export function commentPlugin({ pathMatch, regex }) {
6+
export function commentPlugin() {
117
const PLUGIN_ID = 'comment-override';
128

139
/** @type {import("esbuild").Plugin} */
1410
const plugin = {
1511
name: PLUGIN_ID,
1612
setup(build) {
17-
// watch every import/require and mark matches for processing
18-
build.onResolve({ filter: /.*/ }, (args) => {
19-
const path = join(args.resolveDir, args.path);
20-
if (!path.includes(pathMatch)) return undefined;
21-
22-
// mark this file for processing
23-
return {
24-
path: args.path,
25-
namespace: PLUGIN_ID,
26-
pluginData: {
27-
fullPath: join(args.resolveDir, args.path + '.js'),
28-
},
29-
};
30-
});
31-
32-
// this will only run for files matched above
33-
build.onLoad({ filter: /.*/, namespace: PLUGIN_ID }, async (args) => {
34-
const text = await promises.readFile(args.pluginData.fullPath, 'utf8');
13+
build.onLoad({ filter: /.*/ }, async (args) => {
14+
if (!args.path.includes('node_modules')) return undefined;
15+
const text = await promises.readFile(args.path, 'utf8');
3516
return {
36-
contents: convertToLegalComments(text.toString(), regex),
17+
contents: convertToLegalComments(text.toString()),
3718
loader: 'js',
3819
};
3920
});
@@ -49,31 +30,54 @@ export function commentPlugin({ pathMatch, regex }) {
4930
* When a line is matched, continue to match further lines until a non-comment is seen.
5031
*
5132
* @param {string} source
52-
* @param {RegExp} regex
5333
*/
54-
export function convertToLegalComments(source, regex) {
55-
const lines = [];
56-
57-
let insideCommentBlock = false;
34+
export function convertToLegalComments(source) {
35+
// Process block comments - find all block comments
36+
const blockComments = source.match(/\/\*[\s\S]*?\*\//g) || [];
5837

59-
for (const line of source.split('\n')) {
60-
if (insideCommentBlock) {
61-
if (!line.startsWith('//')) {
62-
insideCommentBlock = false;
63-
}
64-
} else {
65-
if (line.startsWith('//') && line.match(regex)) {
66-
insideCommentBlock = true;
67-
}
38+
// Selectively replace only block comments that contain "copyright"
39+
let modifiedSource = source;
40+
for (const comment of blockComments) {
41+
if (/copyright/i.test(comment)) {
42+
// Replace only the block comments with copyright
43+
modifiedSource = modifiedSource.replace(
44+
comment,
45+
comment.replace(/\/\*/, '/*!')
46+
);
6847
}
48+
}
49+
50+
// Process line comments
51+
const lines = modifiedSource.split('\n');
52+
const result = [];
53+
let inCommentBlock = false;
54+
55+
for (let i = 0; i < lines.length; i++) {
56+
const line = lines[i];
6957

70-
// chose line treatment
71-
if (insideCommentBlock) {
72-
lines.push('//!' + line.slice(2));
73-
} else {
74-
lines.push(line);
58+
// Check if the line contains a block comment - this breaks any line comment sequence
59+
if (line.includes('/*') || line.includes('*/')) {
60+
inCommentBlock = false;
61+
result.push(line);
62+
}
63+
// Check if this line starts a line comment block with "copyright"
64+
else if (!inCommentBlock && /^\s*\/\/(?=.*copyright.*$)/i.test(line)) {
65+
// Start of a copyright comment - mark it and convert
66+
inCommentBlock = true;
67+
result.push(line.replace(/^\s*\/\//, match => match.replace('//', '//!')));
68+
}
69+
// Check if we're continuing a line comment block
70+
else if (inCommentBlock && /^\s*\/\//.test(line)) {
71+
// Continue the comment block - convert the prefix
72+
result.push(line.replace(/^\s*\/\//, match => match.replace('//', '//!')));
73+
}
74+
// Check if we're exiting a comment block
75+
else {
76+
// Not a comment line or doesn't match our criteria, end the block
77+
inCommentBlock = false;
78+
result.push(line);
7579
}
7680
}
7781

78-
return lines.join('\n');
82+
return result.join('\n');
7983
}

injected/unit-test/comment-plugin.js

Lines changed: 179 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,199 @@
11
import { convertToLegalComments } from '../scripts/utils/comment-plugin.js';
22

33
describe('convertToLegalComments', () => {
4-
it('should convert matching comments to legal comments', () => {
5-
const source = '// Copyright\n// All rights reserved\n// 2024';
6-
const regex = /\/\/\s*Copyright/;
7-
const expected = '//! Copyright\n//! All rights reserved\n//! 2024';
4+
it('should convert single line comments with copyright', () => {
5+
const input = `// This is a copyright notice
6+
const foo = 'bar';`;
87

9-
expect(convertToLegalComments(source, regex)).toBe(expected);
8+
const expected = `//! This is a copyright notice
9+
const foo = 'bar';`;
10+
11+
expect(convertToLegalComments(input)).toEqual(expected);
12+
});
13+
14+
it('should convert multiple consecutive line comments following a copyright line', () => {
15+
const input = `// This is a copyright notice
16+
// This is a second line
17+
// This is a third line
18+
const foo = 'bar';`;
19+
20+
const expected = `//! This is a copyright notice
21+
//! This is a second line
22+
//! This is a third line
23+
const foo = 'bar';`;
24+
25+
expect(convertToLegalComments(input)).toEqual(expected);
26+
});
27+
28+
it('should stop converting after a non-comment line is encountered', () => {
29+
const input = `// This is a copyright notice
30+
// This is a second line
31+
const foo = 'bar';
32+
// This is a regular comment that should not be converted`;
33+
34+
const expected = `//! This is a copyright notice
35+
//! This is a second line
36+
const foo = 'bar';
37+
// This is a regular comment that should not be converted`;
38+
39+
expect(convertToLegalComments(input)).toEqual(expected);
40+
});
41+
42+
it('should handle multiple separate comment blocks', () => {
43+
const input = `// This is a regular comment
44+
const a = 1;
45+
46+
// This has copyright info
47+
// And continues here
48+
const b = 2;
49+
50+
// Another copyright notice
51+
// With more details
52+
// And even more info
53+
const c = 3;`;
54+
55+
const expected = `// This is a regular comment
56+
const a = 1;
57+
58+
//! This has copyright info
59+
//! And continues here
60+
const b = 2;
61+
62+
//! Another copyright notice
63+
//! With more details
64+
//! And even more info
65+
const c = 3;`;
66+
67+
expect(convertToLegalComments(input)).toEqual(expected);
68+
});
69+
70+
it('should handle indented comments', () => {
71+
const input = `function test() {
72+
// This has copyright info
73+
// This is indented
74+
return true;
75+
}`;
76+
77+
const expected = `function test() {
78+
//! This has copyright info
79+
//! This is indented
80+
return true;
81+
}`;
82+
83+
expect(convertToLegalComments(input)).toEqual(expected);
1084
});
1185

12-
it("should not convert comments that don't match the regex", () => {
13-
const source = '// Regular comment\n// Another comment';
14-
const regex = /\/\/\s*License/;
86+
it('should handle block comments with copyright', () => {
87+
const input = `/* This is a copyright block comment */
88+
const foo = 'bar';
1589
16-
expect(convertToLegalComments(source, regex)).toBe(source);
90+
/* This is a regular
91+
multiline comment */`;
92+
93+
const expected = `/*! This is a copyright block comment */
94+
const foo = 'bar';
95+
96+
/* This is a regular
97+
multiline comment */`;
98+
99+
expect(convertToLegalComments(input)).toEqual(expected);
17100
});
18101

19-
it('should stop converting when encountering non-comment line', () => {
20-
const source = '// Copyright\n// All rights reserved\ncode line\n// Regular comment';
21-
const regex = /\/\/\s*Copyright/;
22-
const expected = '//! Copyright\n//! All rights reserved\ncode line\n// Regular comment';
102+
it('should handle mixed comment types', () => {
103+
const input = `// This has copyright info
104+
// This continues
105+
/* This is a regular block comment */
106+
const foo = 'bar';
107+
108+
/* This is a copyright block comment */
109+
// This is a regular comment after a block`;
110+
111+
const expected = `//! This has copyright info
112+
//! This continues
113+
/* This is a regular block comment */
114+
const foo = 'bar';
115+
116+
/*! This is a copyright block comment */
117+
// This is a regular comment after a block`;
23118

24-
expect(convertToLegalComments(source, regex)).toBe(expected);
119+
expect(convertToLegalComments(input)).toEqual(expected);
25120
});
26121

27-
it('should handle empty string input', () => {
28-
const regex = /\/\/\s*Copyright/;
122+
it('should handle block comments breaking line comment sequences', () => {
123+
const input = `// This has copyright info
124+
// This line should be converted
125+
/* This block comment breaks the sequence */
126+
// This line should NOT be converted
127+
// Even though it follows another comment`;
29128

30-
expect(convertToLegalComments('', regex)).toBe('');
129+
const expected = `//! This has copyright info
130+
//! This line should be converted
131+
/* This block comment breaks the sequence */
132+
// This line should NOT be converted
133+
// Even though it follows another comment`;
134+
135+
expect(convertToLegalComments(input)).toEqual(expected);
31136
});
32137

33-
it('should handle multiple comment blocks', () => {
34-
const source = '// Copyright\n// Notice\ncode\n// Copyright\n// Notice';
35-
const regex = /\/\/\s*Copyright/;
36-
const expected = '//! Copyright\n//! Notice\ncode\n//! Copyright\n//! Notice';
138+
it('should handle case insensitivity for "copyright"', () => {
139+
const input = `// This has COPYRIGHT info
140+
// This continues
141+
const foo = 'bar';
142+
143+
// This has Copyright mixed case
144+
// More comments
145+
const baz = 'qux';`;
146+
147+
const expected = `//! This has COPYRIGHT info
148+
//! This continues
149+
const foo = 'bar';
37150
38-
expect(convertToLegalComments(source, regex)).toBe(expected);
151+
//! This has Copyright mixed case
152+
//! More comments
153+
const baz = 'qux';`;
154+
155+
expect(convertToLegalComments(input)).toEqual(expected);
39156
});
40157

41-
it('should preserve leading spaces in comments', () => {
42-
const source = '// Copyright\n// All rights reserved';
43-
const regex = /\/\/\s*Copyright/;
44-
const expected = '//! Copyright\n//! All rights reserved';
158+
it('should not convert comments without copyright', () => {
159+
const input = `// This is a regular comment
160+
// Another regular comment
161+
const foo = 'bar';`;
162+
163+
const expected = `// This is a regular comment
164+
// Another regular comment
165+
const foo = 'bar';`;
166+
167+
expect(convertToLegalComments(input)).toEqual(expected);
168+
});
169+
170+
it('should handle code with no comments', () => {
171+
const input = `const foo = 'bar';
172+
function test() {
173+
return true;
174+
}
175+
const obj = { key: 'value' };`;
176+
177+
const expected = input; // Should remain unchanged
178+
179+
expect(convertToLegalComments(input)).toEqual(expected);
180+
});
181+
182+
it('should treat empty lines as non-comment lines that break the sequence', () => {
183+
const input = `// This has copyright info
184+
// This continues
185+
186+
// These comments should NOT be converted
187+
// Because empty line breaks the sequence
188+
const foo = 'bar';`;
189+
190+
const expected = `//! This has copyright info
191+
//! This continues
192+
193+
// These comments should NOT be converted
194+
// Because empty line breaks the sequence
195+
const foo = 'bar';`;
45196

46-
expect(convertToLegalComments(source, regex)).toBe(expected);
197+
expect(convertToLegalComments(input)).toEqual(expected);
47198
});
48-
});
199+
});

0 commit comments

Comments
 (0)