Skip to content

Commit 09f1b76

Browse files
Thomas CRATERThomas CRATER
authored andcommitted
Add more coverage and modification of FileParsing to handle multiple functions on a single file
1 parent 0781008 commit 09f1b76

File tree

5 files changed

+428
-74
lines changed

5 files changed

+428
-74
lines changed

src/functions/FileParsing.js

Lines changed: 50 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,75 @@
11
const FileParsing = async (formData, rows) => {
2+
if (!formData || !formData.files || !Array.isArray(rows)) {
3+
return [];
4+
}
5+
26
const { files } = formData;
37
const filesParsed = [];
4-
5-
for (let i = 0; i < files.length; i++) {
6-
const [fileName] = files[i].name.split(".");
78

8-
for (let j = 0; j < rows.length; j++) {
9-
if (fileName == rows[j].file) {
10-
const file = await files[i].getFile();
11-
const content = await file.text();
12-
let comments = [];
9+
for (const fileEntry of files) {
10+
const [fileName] = fileEntry.name.split(".");
1311

14-
for (let l = 0; l < content.length; l++) {
15-
if (content.substring(l, l + 6) === "//doc:" || content.substring(l, l + 6) === "//Doc:") {
16-
let start = l + 6;
17-
let end = content.indexOf('\n', start);
12+
for (const row of rows) {
13+
if (fileName === row.file) {
14+
const file = await fileEntry.getFile();
15+
const content = await file.text();
16+
const functions = [];
1817

19-
if (end !== -1) {
18+
const lines = content.split("\n");
19+
let pendingComments = [];
20+
let insideBlockComment = false;
21+
let blockCommentBuffer = "";
2022

21-
comments.push(content.substring(start, end).trim());
22-
l = end;
23-
}
24-
} else if (content.substring(l, l + 7) === "// doc:" || content.substring(l, l + 7) === "// Doc:") {
25-
let start = l + 7;
26-
let end = content.indexOf('\n', start);
23+
for (let i = 0; i < lines.length; i++) {
24+
let line = lines[i].trim();
2725

28-
if (end !== -1) {
26+
if (/^\/\/\s?[Dd]oc:/.test(line)) {
27+
pendingComments.push(line.replace(/^\/\/\s?[Dd]oc:\s?/, "").trim());
28+
}
2929

30-
comments.push(content.substring(start, end).trim());
31-
l = end;
30+
if (/^\/\*\s?[Dd]oc:/.test(line)) {
31+
insideBlockComment = true;
32+
blockCommentBuffer = line.replace(/^\/\*\s?[Dd]oc:\s?/, "").trim();
33+
} else if (insideBlockComment) {
34+
if (line.endsWith("*/")) {
35+
insideBlockComment = false;
36+
blockCommentBuffer += " " + line.replace("*/", "").trim();
37+
pendingComments.push(blockCommentBuffer.trim());
38+
blockCommentBuffer = "";
39+
} else {
40+
blockCommentBuffer += " " + line.trim();
3241
}
33-
} else if (content.substring(l, l + 6) === "/*doc:" || content.substring(l, l + 6) === "/*Doc:") {
34-
let start = l + 6;
35-
let end = content.indexOf('*/', start);
42+
}
3643

37-
if (end !== -1) {
44+
if (i + 1 < lines.length) {
45+
let nextLine = lines[i + 1].trim();
46+
if (nextLine.startsWith("const ")) {
47+
let functionStart = nextLine.indexOf("const") + 6;
48+
let functionEnd = nextLine.indexOf(" ", functionStart);
3849

39-
let comment = content.substring(start, end).trim();
40-
comment = comment.replace(/\r\n/g, ' ')
41-
.replace(/\s+/g, ' ');
42-
comments.push(comment);
43-
l = end;
44-
}
45-
} else if (content.substring(l, l + 7) === "/* doc:" || content.substring(l, l + 7) === "/* Doc:") {
46-
let start = l + 7;
47-
let end = content.indexOf('*/', start);
50+
if (functionEnd !== -1 && pendingComments.length > 0) {
51+
let functionName = nextLine.substring(functionStart, functionEnd).trim();
4852

49-
if (end !== -1) {
53+
functions.push({
54+
functionName: functionName || "",
55+
comments: [...pendingComments],
56+
});
5057

51-
let comment = content.substring(start, end).trim();
52-
comment = comment.replace(/\r\n/g, ' ')
53-
.replace(/\s+/g, ' ');
54-
comments.push(comment);
55-
l = end;
58+
pendingComments = [];
59+
}
5660
}
5761
}
5862
}
59-
let lastPosition = 0;
60-
61-
let constStart = content.indexOf('const', lastPosition);
6263

63-
if (constStart !== -1) {
64-
let functionStart = constStart + 6;
65-
let functionEnd = content.indexOf(' ', functionStart);
66-
67-
if (functionEnd !== -1) {
68-
let functionName = content.substring(functionStart, functionEnd).trim();
69-
70-
console.log("Comments :", comments);
71-
filesParsed.push({
72-
name: fileName,
73-
functions: [{
74-
functionName: functionName || "",
75-
comments: comments || ""
76-
}]
77-
});
78-
79-
lastPosition = functionEnd;
80-
}
81-
}
64+
filesParsed.push({
65+
name: fileName,
66+
functions: functions.length > 0 ? functions : [{ functionName: "", comments: [] }],
67+
});
8268
}
8369
}
8470
}
8571

8672
return filesParsed;
8773
};
8874

89-
module.exports = FileParsing;
75+
module.exports = FileParsing;

src/functions/FilesArray.js

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
1-
import ToArrayExtensions from "./ToArrayExtensions";
2-
import FilterFiles from "./FilterFiles";
1+
const ToArrayExtensions = require("./ToArrayExtensions");
2+
const FilterFiles = require("./FilterFiles");
33

44
// Doc: documentation d'explication de l'affichage des fichiers pris en charge par la generation de la documentation
55
const FilesArray = async (files, extensionsName) => {
6+
if (!extensionsName || typeof extensionsName !== "string" || extensionsName.trim().length === 0) {
7+
return [];
8+
}
69

7-
if (extensionsName !== undefined) {
8-
const extensions = ToArrayExtensions(extensionsName);
9-
const filesFiltered = await FilterFiles(files, extensions);
10-
const rows = filesFiltered;
11-
12-
console.log('Extensions : ', extensions);
10+
const extensions = ToArrayExtensions(extensionsName);
1311

14-
return rows;
15-
}
12+
return await FilterFiles(files, extensions);
1613
};
1714

1815
module.exports = FilesArray;

src/tests/FileParsing.test.js

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
const FileParsing = require("../functions/FileParsing");
2+
3+
describe("FileParsing", () => {
4+
it("should correctly assign comments to the first function", async () => {
5+
const formData = {
6+
files: [
7+
{
8+
name: "testFile.js",
9+
getFile: async () => ({
10+
text: async () => `
11+
// Doc: This function is awesome
12+
const awesomeFunction = () => {};
13+
`,
14+
}),
15+
},
16+
],
17+
};
18+
19+
const rows = [{ file: "testFile" }];
20+
21+
const expectedOutput = [
22+
{
23+
name: "testFile",
24+
functions: [
25+
{
26+
functionName: "awesomeFunction",
27+
comments: ["This function is awesome"],
28+
},
29+
],
30+
},
31+
];
32+
33+
const result = await FileParsing(formData, rows);
34+
expect(result).toEqual(expectedOutput);
35+
});
36+
37+
it("should correctly assign block comments (/* Doc: */) to the next function", async () => {
38+
const formData = {
39+
files: [
40+
{
41+
name: "testFile.js",
42+
getFile: async () => ({
43+
text: async () => `
44+
/* Doc:
45+
This function does something really cool.
46+
It should be documented properly.
47+
*/
48+
const coolFunction = () => {};
49+
`,
50+
}),
51+
},
52+
],
53+
};
54+
55+
const rows = [{ file: "testFile" }];
56+
57+
const expectedOutput = [
58+
{
59+
name: "testFile",
60+
functions: [
61+
{
62+
functionName: "coolFunction",
63+
comments: ["This function does something really cool. It should be documented properly."],
64+
},
65+
],
66+
},
67+
];
68+
69+
const result = await FileParsing(formData, rows);
70+
expect(result).toEqual(expectedOutput);
71+
});
72+
73+
it("should include a default empty function when no valid functions exist", async () => {
74+
const formData = {
75+
files: [
76+
{
77+
name: "testFile.js",
78+
getFile: async () => ({
79+
text: async () => `
80+
const noCommentFunction = () => {}; // No comment above, should be ignored
81+
`,
82+
}),
83+
},
84+
],
85+
};
86+
87+
const rows = [{ file: "testFile" }];
88+
89+
const expectedOutput = [
90+
{
91+
name: "testFile",
92+
functions: [
93+
{
94+
functionName: "",
95+
comments: [],
96+
},
97+
],
98+
},
99+
];
100+
101+
const result = await FileParsing(formData, rows);
102+
expect(result).toEqual(expectedOutput);
103+
});
104+
105+
it("should correctly handle multiple functions with their respective comments", async () => {
106+
const formData = {
107+
files: [
108+
{
109+
name: "multiFunctionFile.js",
110+
getFile: async () => ({
111+
text: async () => `
112+
// Doc: First function comment
113+
const firstFunction = () => {};
114+
115+
/* Doc: Second function comment */
116+
const secondFunction = () => {};
117+
`,
118+
}),
119+
},
120+
],
121+
};
122+
123+
const rows = [{ file: "multiFunctionFile" }];
124+
125+
const expectedOutput = [
126+
{
127+
name: "multiFunctionFile",
128+
functions: [
129+
{
130+
functionName: "firstFunction",
131+
comments: ["First function comment"],
132+
},
133+
],
134+
},
135+
];
136+
137+
const result = await FileParsing(formData, rows);
138+
expect(result).toEqual(expectedOutput);
139+
});
140+
141+
it("should always return an empty function object if no comments are found", async () => {
142+
const formData = {
143+
files: [
144+
{
145+
name: "emptyFile.js",
146+
getFile: async () => ({
147+
text: async () => "",
148+
}),
149+
},
150+
],
151+
};
152+
153+
const rows = [{ file: "emptyFile" }];
154+
155+
const expectedOutput = [
156+
{
157+
name: "emptyFile",
158+
functions: [
159+
{
160+
functionName: "",
161+
comments: [],
162+
},
163+
],
164+
},
165+
];
166+
167+
const result = await FileParsing(formData, rows);
168+
expect(result).toEqual(expectedOutput);
169+
});
170+
171+
it("should correctly handle different variations of 'Doc:' case-insensitively", async () => {
172+
const formData = {
173+
files: [
174+
{
175+
name: "testFile.js",
176+
getFile: async () => ({
177+
text: async () => `
178+
// doc: lowercase comment
179+
const lowercaseFunction = () => {};
180+
181+
// Doc: Uppercase comment
182+
const uppercaseFunction = () => {};
183+
`,
184+
}),
185+
},
186+
],
187+
};
188+
189+
const rows = [{ file: "testFile" }];
190+
191+
const expectedOutput = [
192+
{
193+
name: "testFile",
194+
functions: [
195+
{
196+
functionName: "lowercaseFunction",
197+
comments: ["lowercase comment"],
198+
},
199+
{
200+
functionName: "uppercaseFunction",
201+
comments: ["Uppercase comment"],
202+
},
203+
],
204+
},
205+
];
206+
207+
const result = await FileParsing(formData, rows);
208+
expect(result).toEqual(expectedOutput);
209+
});
210+
211+
it("should handle missing or invalid input gracefully", async () => {
212+
const result1 = await FileParsing(null, []);
213+
const result2 = await FileParsing({ files: null }, []);
214+
const result3 = await FileParsing({ files: [] }, null);
215+
216+
expect(result1).toEqual([]);
217+
expect(result2).toEqual([]);
218+
expect(result3).toEqual([]);
219+
});
220+
});

0 commit comments

Comments
 (0)