Skip to content

Commit 25ff1ee

Browse files
committed
got ts errors with parent prop, changed it to match the tree type, added my testing suite to this branch and files, all of the tests in 14 works except the component1. not sure why
1 parent 74a4dcd commit 25ff1ee

File tree

3 files changed

+172
-93
lines changed

3 files changed

+172
-93
lines changed

src/parser.ts

Lines changed: 85 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export class Parser {
4949
reactRouter: false,
5050
reduxConnect: false,
5151
children: [],
52-
parent: null,
52+
parent: '',
5353
parentList: [],
5454
props: {},
5555
error: '',
@@ -61,7 +61,7 @@ export class Parser {
6161
}
6262

6363
public getTree(): Tree {
64-
return this.tree;
64+
return this.tree!;
6565
}
6666

6767
// Set entryFile property with the result of Parser (from workspace state)
@@ -270,7 +270,7 @@ export class Parser {
270270
}
271271

272272
// Determines server or client component type (looks for use of 'use client' and react/redux state hooks)
273-
private getComponentType(directive: { [key: string]: any }[], body: { [key: string]: any }[]): boolean {
273+
private getComponentType(directive: { [key: string]: any }[], body: { [key: string]: any }[]) {
274274
const defaultErr = (err) => {
275275
return {
276276
method: 'Error in getCallee method of Parser:',
@@ -290,8 +290,18 @@ export class Parser {
290290
}
291291

292292
// Second check for use of React/Redux hooks
293+
294+
// Checks for components declared using 'const'
293295
const bodyCallee = body.filter((item) => item.type === 'VariableDeclaration');
294-
if (bodyCallee.length === 0) return false;
296+
// console.log('body: ', bodyCallee);
297+
298+
// Checks for components declared using 'export default function'
299+
const exportCallee = body.filter((item) => item.type === 'ExportDefaultDeclaration');
300+
// console.log('exprt: ', exportCallee);
301+
302+
// Checks for components declared using 'function'
303+
const functionCallee = body.filter((item) => item.type === 'FunctionDeclaration');
304+
// console.log('func: ', functionCallee);
295305

296306
// Helper function
297307
const calleeHelper = (item) => {
@@ -345,7 +355,74 @@ export class Parser {
345355
return false;
346356
}
347357

348-
if (bodyCallee.length === 1) {
358+
// Calling helper function for functionCallee array with length of 1 or more
359+
if (functionCallee.length === 1) {
360+
const calleeArr = functionCallee[0].body?.body;
361+
if (calleeArr === undefined) return false;
362+
363+
let checkTrue = false;
364+
for (let i = 0; i < calleeArr.length; i++) {
365+
if (checkTrue) return true;
366+
checkTrue = calleeHelper(calleeArr[i]);
367+
}
368+
return checkTrue;
369+
} else if (functionCallee.length > 1) {
370+
let calleeArr: [] = [];
371+
for (let i = 0; i < functionCallee.length; i++) {
372+
try {
373+
if (functionCallee[i].declarations[0]?.init?.body?.body) {
374+
calleeArr = functionCallee[i].declarations[0].init.body.body;
375+
}
376+
}
377+
catch (err) {
378+
const error = defaultErr(err);
379+
console.error(error.method, '\n', error.log);
380+
}
381+
}
382+
383+
if (calleeArr === undefined) return false;
384+
let checkTrue = false;
385+
for (let i = 0; i < calleeArr.length; i++) {
386+
if (checkTrue) return true;
387+
checkTrue = calleeHelper(calleeArr[i]);
388+
}
389+
return checkTrue;
390+
391+
// Calling helper function for exportCallee array with length of 1 or more
392+
} else if (exportCallee.length === 1) {
393+
const calleeArr = exportCallee[0].declaration.body?.body;
394+
if (calleeArr === undefined) return false;
395+
396+
let checkTrue = false;
397+
for (let i = 0; i < calleeArr.length; i++) {
398+
if (checkTrue) return true;
399+
checkTrue = calleeHelper(calleeArr[i]);
400+
}
401+
return checkTrue;
402+
} else if (exportCallee.length > 1) {
403+
let calleeArr: [] = [];
404+
for (let i = 0; i < exportCallee.length; i++) {
405+
try {
406+
if (exportCallee[i].declarations[0]?.init?.body?.body) {
407+
calleeArr = exportCallee[i].declarations[0].init.body.body;
408+
}
409+
}
410+
catch (err) {
411+
const error = defaultErr(err);
412+
console.error(error.method, '\n', error.log);
413+
}
414+
}
415+
416+
if (calleeArr === undefined) return false;
417+
let checkTrue = false;
418+
for (let i = 0; i < calleeArr.length; i++) {
419+
if (checkTrue) return true;
420+
checkTrue = calleeHelper(calleeArr[i]);
421+
}
422+
return checkTrue;
423+
424+
// Calling helper function for bodyCallee array with length of 1 or more
425+
} else if (bodyCallee.length === 1) {
349426
const calleeArr = bodyCallee[0].declarations[0]?.init?.body?.body;
350427
if (calleeArr === undefined) return false;
351428

@@ -355,9 +432,8 @@ export class Parser {
355432
checkTrue = calleeHelper(calleeArr[i]);
356433
}
357434
return checkTrue;
358-
}
359-
else if (bodyCallee.length > 1) {
360-
let calleeArr: [];
435+
} else if (bodyCallee.length > 1) {
436+
let calleeArr: [] = [];
361437
for (let i = 0; i < bodyCallee.length; i++) {
362438
try {
363439
if (bodyCallee[i].declarations[0]?.init?.body?.body) {
@@ -378,6 +454,7 @@ export class Parser {
378454
}
379455
return checkTrue;
380456
}
457+
if (!bodyCallee && !exportCallee && !functionCallee) return false;
381458
}
382459

383460
// Finds JSX React Components in current file

src/test/suite/parser.test.ts

Lines changed: 83 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -6,96 +6,97 @@ describe('Parser Test Suite', () => {
66
let parser, tree, file;
77

88
// TEST 11: PARSER DOESN'T BREAK UPON RECURSIVE COMPONENTS
9-
describe('It should render the second call of mutually recursive components, but no further', () => {
10-
beforeAll(() => {
11-
file = path.join(__dirname, '../../../../src/test/test_cases/tc_11/index.js');
12-
parser = new Parser(file);
13-
tree = parser.parse();
14-
});
15-
16-
test('Tree should not be undefined', () => {
17-
expect(tree).toBeDefined();
18-
});
19-
20-
test('Tree should have an index component while child App1, grandchild App2, great-grandchild App1', () => {
21-
expect(tree).toHaveProperty('name', 'index');
22-
expect(tree.children).toHaveLength(1);
23-
expect(tree.children[0]).toHaveProperty('name', 'App1');
24-
expect(tree.children[0].children).toHaveLength(1);
25-
expect(tree.children[0].children[0]).toHaveProperty('name', 'App2');
26-
expect(tree.children[0].children[0].children).toHaveLength(1);
27-
expect(tree.children[0].children[0].children[0]).toHaveProperty('name', 'App1');
28-
expect(tree.children[0].children[0].children[0].children).toHaveLength(0);
29-
});
30-
});
31-
32-
// TEST 12A: NEXT.JS APPS (pages router)
33-
describe('It should parse Next.js applications using Pages Router', () => {
34-
beforeAll(() => {
35-
file = path.join(__dirname, '../../../../src/test/test_cases/tc_12a/pages/index.js');
36-
parser = new Parser(file);
37-
tree = parser.parse();
38-
});
39-
40-
test('Root should be named index, children should be named Head and Navbar, children of Navbar should be named Link and Image', () => {
41-
expect(tree).toHaveProperty('name', 'index');
42-
expect(tree.children).toHaveLength(2);
43-
expect(tree.children[0]).toHaveProperty('name', 'Head');
44-
expect(tree.children[1]).toHaveProperty('name', 'Navbar');
45-
46-
expect(tree.children[1].children).toHaveLength(2);
47-
expect(tree.children[1].children[0]).toHaveProperty('name', 'Link');
48-
expect(tree.children[1].children[1]).toHaveProperty('name', 'Image');
49-
});
50-
});
51-
52-
// TEST 12B: NEXT.JS APPS (app router)
53-
describe('It should parser Next.js applications using Apps Router', () => {
54-
beforeAll(() => {
55-
file = path.join(__dirname, '../../../../src/test/test_cases/tc_12b/app/page.jsx');
56-
parser = new Parser(file);
57-
tree = parser.parse();
58-
});
59-
60-
test('Root should be named page, it should have one child named Homepage', () => {
61-
expect(tree).toHaveProperty('name', 'page');
62-
expect(tree.children).toHaveLength(1);
63-
expect(tree.children[0]).toHaveProperty('name', 'HomePage');
64-
});
65-
});
9+
// describe('It should render the second call of mutually recursive components, but no further', () => {
10+
// beforeAll(() => {
11+
// file = path.join(__dirname, '../../../../src/test/test_cases/tc_11/index.js');
12+
// parser = new Parser(file);
13+
// tree = parser.parse();
14+
// });
15+
16+
// test('Tree should not be undefined', () => {
17+
// expect(tree).toBeDefined();
18+
// });
19+
20+
// test('Tree should have an index component while child App1, grandchild App2, great-grandchild App1', () => {
21+
// expect(tree).toHaveProperty('name', 'index');
22+
// expect(tree.children).toHaveLength(1);
23+
// expect(tree.children[0]).toHaveProperty('name', 'App1');
24+
// expect(tree.children[0].children).toHaveLength(1);
25+
// expect(tree.children[0].children[0]).toHaveProperty('name', 'App2');
26+
// expect(tree.children[0].children[0].children).toHaveLength(1);
27+
// expect(tree.children[0].children[0].children[0]).toHaveProperty('name', 'App1');
28+
// expect(tree.children[0].children[0].children[0].children).toHaveLength(0);
29+
// });
30+
// });
31+
32+
// // TEST 12A: NEXT.JS APPS (pages router)
33+
// describe('It should parse Next.js applications using Pages Router', () => {
34+
// beforeAll(() => {
35+
// file = path.join(__dirname, '../../../../src/test/test_cases/tc_12a/pages/index.js');
36+
// parser = new Parser(file);
37+
// tree = parser.parse();
38+
// });
39+
40+
// test('Root should be named index, children should be named Head and Navbar, children of Navbar should be named Link and Image', () => {
41+
// expect(tree).toHaveProperty('name', 'index');
42+
// expect(tree.children).toHaveLength(2);
43+
// expect(tree.children[0]).toHaveProperty('name', 'Head');
44+
// expect(tree.children[1]).toHaveProperty('name', 'Navbar');
45+
46+
// expect(tree.children[1].children).toHaveLength(2);
47+
// expect(tree.children[1].children[0]).toHaveProperty('name', 'Link');
48+
// expect(tree.children[1].children[1]).toHaveProperty('name', 'Image');
49+
// });
50+
// });
51+
52+
// // TEST 12B: NEXT.JS APPS (app router)
53+
// describe('It should parser Next.js applications using Apps Router', () => {
54+
// beforeAll(() => {
55+
// file = path.join(__dirname, '../../../../src/test/test_cases/tc_12b/app/page.jsx');
56+
// parser = new Parser(file);
57+
// tree = parser.parse();
58+
// });
59+
60+
// test('Root should be named page, it should have one child named Homepage', () => {
61+
// expect(tree).toHaveProperty('name', 'page');
62+
// expect(tree.children).toHaveLength(1);
63+
// expect(tree.children[0]).toHaveProperty('name', 'HomePage');
64+
// });
65+
// });
6666

67-
// TEST 13: VARIABLE DECLARATION IMPORTS AND REACT.LAZY IMPORTS
68-
describe('It should parse VariableDeclaration imports including React.lazy imports', () => {
69-
beforeAll(() => {
70-
file = path.join(__dirname, '../../../../src/test/test_cases/tc_13/index.js');
71-
parser = new Parser(file);
72-
tree = parser.parse();
73-
});
74-
75-
test('Root should be named index, it should have one child named App', () => {
76-
expect(tree).toHaveProperty('name', 'index');
77-
expect(tree.children).toHaveLength(1);
78-
expect(tree.children[0]).toHaveProperty('name', 'App');
79-
});
80-
81-
test('App should have three children, Component1, Component2 and Component3, all found successfully', () => {
82-
expect(tree.children[0].children[0]).toHaveProperty('name', 'Component1');
83-
expect(tree.children[0].children[0]).toHaveProperty('thirdParty', false);
84-
85-
expect(tree.children[0].children[1]).toHaveProperty('name', 'Component2');
86-
expect(tree.children[0].children[1]).toHaveProperty('thirdParty', false);
87-
88-
expect(tree.children[0].children[2]).toHaveProperty('name', 'Component3');
89-
expect(tree.children[0].children[2]).toHaveProperty('thirdParty', false);
90-
});
91-
});
67+
// // TEST 13: VARIABLE DECLARATION IMPORTS AND REACT.LAZY IMPORTS
68+
// describe('It should parse VariableDeclaration imports including React.lazy imports', () => {
69+
// beforeAll(() => {
70+
// file = path.join(__dirname, '../../../../src/test/test_cases/tc_13/index.js');
71+
// parser = new Parser(file);
72+
// tree = parser.parse();
73+
// });
74+
75+
// test('Root should be named index, it should have one child named App', () => {
76+
// expect(tree).toHaveProperty('name', 'index');
77+
// expect(tree.children).toHaveLength(1);
78+
// expect(tree.children[0]).toHaveProperty('name', 'App');
79+
// });
80+
81+
// test('App should have three children, Component1, Component2 and Component3, all found successfully', () => {
82+
// expect(tree.children[0].children[0]).toHaveProperty('name', 'Component1');
83+
// expect(tree.children[0].children[0]).toHaveProperty('thirdParty', false);
84+
85+
// expect(tree.children[0].children[1]).toHaveProperty('name', 'Component2');
86+
// expect(tree.children[0].children[1]).toHaveProperty('thirdParty', false);
87+
88+
// expect(tree.children[0].children[2]).toHaveProperty('name', 'Component3');
89+
// expect(tree.children[0].children[2]).toHaveProperty('thirdParty', false);
90+
// });
91+
// });
9292

9393
// TEST 14: CHECK IF COMPONENT IS A CLIENT COMPONENT USING HOOKS AND DIRECTIVES
9494
describe('It should parse components and determine if the component type', () => {
9595
beforeAll(() => {
9696
file = path.join(__dirname, '../../../../src/test/test_cases/tc_14/index.js');
9797
parser = new Parser(file);
9898
tree = parser.parse();
99+
// console.log('tree:', tree.children[0].children[0]);
99100
});
100101

101102
test('Root should be named index, it should have one children named App', () => {
@@ -107,9 +108,6 @@ describe('Parser Test Suite', () => {
107108
test('App should have three children, Component1 is a client component using hooks (variable declaration, export default declaration, and function declaration), Component2 is a client component using directives, and Component3 is not a client component', () => {
108109
expect(tree.children[0].children[0]).toHaveProperty('name', 'Component1');
109110
expect(tree.children[0].children[0]).toHaveProperty('isClientComponent', true);
110-
expect(typeof tree.children[0].children[0]).toBe('function');
111-
expect(typeof tree.children[0].children[0]).not.toBe('undefined');
112-
expect(typeof tree.children[0].children[0]).not.toBe('function');
113111

114112
expect(tree.children[0].children[1]).toHaveProperty('name', 'Component2');
115113
expect(tree.children[0].children[1]).toHaveProperty('isClientComponent', true);

src/test/test_cases/tc_14/components/App.jsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@ import React from 'react';
22
import Component1 from './Component1';
33
import Component2 from "./Component2";
44
import Component3 from "./Component3";
5+
import Component4 from "./Component4";
6+
import Component5 from "./Component5";
57

68
export default function Pages() {
79
return (
810
<div>
911
<Component1 />
1012
<Component2 />
1113
<Component3 />
14+
<Component4 />
15+
<Component5 />
1216
</div>
1317
);
1418
}

0 commit comments

Comments
 (0)