ts2famix 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +24 -0
- package/.github/workflows/node.js.yml +60 -0
- package/LICENSE +23 -0
- package/README.md +111 -0
- package/doc-metamodel/skins.include.puml +2 -0
- package/jest.config.ts +199 -0
- package/package.json +47 -0
- package/src/analyze.ts +90 -0
- package/src/analyze_functions/processAccesses.ts +50 -0
- package/src/analyze_functions/processFiles.ts +656 -0
- package/src/analyze_functions/processImportClauses.ts +77 -0
- package/src/analyze_functions/processInheritances.ts +84 -0
- package/src/analyze_functions/processInvocations.ts +51 -0
- package/src/famix2puml.ts +119 -0
- package/src/famix_functions/famix_functions.ts +552 -0
- package/src/famix_functions/famix_functions_associations.ts +208 -0
- package/src/famix_functions/famix_functions_index.ts +44 -0
- package/src/famix_functions/famix_functions_types.ts +100 -0
- package/src/fqn.ts +127 -0
- package/src/fqp_implementation.ts +66 -0
- package/src/generate_uml.sh +16 -0
- package/src/lib/famix/License.md +23 -0
- package/src/lib/famix/package-lock.json +301 -0
- package/src/lib/famix/package.json +28 -0
- package/src/lib/famix/readme.md +5 -0
- package/src/lib/famix/src/famix_JSON_exporter.ts +56 -0
- package/src/lib/famix/src/famix_base_element.ts +18 -0
- package/src/lib/famix/src/famix_repository.ts +199 -0
- package/src/lib/famix/src/index.ts +8 -0
- package/src/lib/famix/src/model/famix/access.ts +53 -0
- package/src/lib/famix/src/model/famix/accessor.ts +15 -0
- package/src/lib/famix/src/model/famix/alias.ts +41 -0
- package/src/lib/famix/src/model/famix/association.ts +44 -0
- package/src/lib/famix/src/model/famix/behavioral_entity.ts +107 -0
- package/src/lib/famix/src/model/famix/c_source_language.ts +15 -0
- package/src/lib/famix/src/model/famix/class.ts +86 -0
- package/src/lib/famix/src/model/famix/comment.ts +50 -0
- package/src/lib/famix/src/model/famix/container_entity.ts +165 -0
- package/src/lib/famix/src/model/famix/custom_source_language.ts +27 -0
- package/src/lib/famix/src/model/famix/decorator.ts +39 -0
- package/src/lib/famix/src/model/famix/entity.ts +15 -0
- package/src/lib/famix/src/model/famix/enum.ts +31 -0
- package/src/lib/famix/src/model/famix/enum_value.ts +29 -0
- package/src/lib/famix/src/model/famix/function.ts +15 -0
- package/src/lib/famix/src/model/famix/implicit_variable.ts +15 -0
- package/src/lib/famix/src/model/famix/import_clause.ts +53 -0
- package/src/lib/famix/src/model/famix/index.ts +42 -0
- package/src/lib/famix/src/model/famix/indexed_file_anchor.ts +49 -0
- package/src/lib/famix/src/model/famix/inheritance.ts +42 -0
- package/src/lib/famix/src/model/famix/interface.ts +75 -0
- package/src/lib/famix/src/model/famix/invocation.ts +68 -0
- package/src/lib/famix/src/model/famix/method.ts +96 -0
- package/src/lib/famix/src/model/famix/module.ts +31 -0
- package/src/lib/famix/src/model/famix/named_entity.ts +98 -0
- package/src/lib/famix/src/model/famix/namespace.ts +28 -0
- package/src/lib/famix/src/model/famix/parameter.ts +29 -0
- package/src/lib/famix/src/model/famix/parameterizable_class.ts +31 -0
- package/src/lib/famix/src/model/famix/parameterizable_interface.ts +31 -0
- package/src/lib/famix/src/model/famix/parameterized_type.ts +40 -0
- package/src/lib/famix/src/model/famix/primitive_type.ts +15 -0
- package/src/lib/famix/src/model/famix/property.ts +54 -0
- package/src/lib/famix/src/model/famix/reference.ts +42 -0
- package/src/lib/famix/src/model/famix/scoping_entity.ts +31 -0
- package/src/lib/famix/src/model/famix/script_entity.ts +38 -0
- package/src/lib/famix/src/model/famix/source_anchor.ts +31 -0
- package/src/lib/famix/src/model/famix/source_language.ts +31 -0
- package/src/lib/famix/src/model/famix/sourced_entity.ts +70 -0
- package/src/lib/famix/src/model/famix/structural_entity.ts +44 -0
- package/src/lib/famix/src/model/famix/text_anchor.ts +49 -0
- package/src/lib/famix/src/model/famix/type.ts +88 -0
- package/src/lib/famix/src/model/famix/type_parameter.ts +33 -0
- package/src/lib/famix/src/model/famix/variable.ts +28 -0
- package/src/lib/famix/tsconfig.json +27 -0
- package/src/lib/famix/tslint.json +15 -0
- package/src/lib/ts-complex/cyclomatic-service.ts +85 -0
- package/src/ts2famix-cli.ts +26 -0
- package/src/ts2famix-tsconfig.ts +30 -0
- package/test/abstractClassWithComments.test.ts +58 -0
- package/test/abstracts.test.ts +53 -0
- package/test/access.test.ts +62 -0
- package/test/accesses.test.ts +42 -0
- package/test/accessorsWithDecorators.test.ts +98 -0
- package/test/alias.test.ts +39 -0
- package/test/classExtendsUndefinedClass.test.ts +41 -0
- package/test/classImplementsUndefinedInterface.test.ts +45 -0
- package/test/classWithDecorators.test.ts +65 -0
- package/test/entities.test.ts +232 -0
- package/test/entities_json.test.ts +48 -0
- package/test/enum.test.ts +55 -0
- package/test/functionReturnsFunction.test.ts +53 -0
- package/test/functionWithParameters.test.ts +38 -0
- package/test/functionWithVariables.test.ts +64 -0
- package/test/functions.test.ts +23 -0
- package/test/functionsInFunction.test.ts +40 -0
- package/test/functionsInMethod.test.ts +42 -0
- package/test/genericClass.test.ts +42 -0
- package/test/genericClassInheritsInterface.test.ts +47 -0
- package/test/genericInterface.test.ts +38 -0
- package/test/genericMethod.test.ts +65 -0
- package/test/genericWithInvocation.test.ts +71 -0
- package/test/generics.test.ts +68 -0
- package/test/inheritance.test.ts +50 -0
- package/test/interfaceInheritsInterface.test.ts +40 -0
- package/test/interfaceInheritsUndefinedInterface.test.ts +41 -0
- package/test/invocation.test.ts +94 -0
- package/test/invocationWithFunction.test.ts +42 -0
- package/test/invocationWithVariable.test.ts +46 -0
- package/test/invocation_json.test.ts +63 -0
- package/test/invocations.test.ts +131 -0
- package/test/jsDoc.test.ts +31 -0
- package/test/methodWithDecorator.test.ts +44 -0
- package/test/methods.test.ts +42 -0
- package/test/metrics.test.ts +51 -0
- package/test/module.test.ts +71 -0
- package/test/namespaces.test.ts +54 -0
- package/test/namespacesAndClasses.test.ts +66 -0
- package/test/parameterWithDecorators.test.ts +54 -0
- package/test/propertyWithDecorators.test.ts +80 -0
- package/test/sample.test.ts +13 -0
- package/test/simpleFunction.test.ts +32 -0
- package/test/simpleTest.test.ts +18 -0
- package/test/simpleTest2.test.ts +36 -0
- package/test/types.test.ts +58 -0
- package/test_src/sample.ts +103 -0
- package/test_src/sampleForModule.ts +10 -0
- package/test_src/sampleForModule2.ts +7 -0
- package/test_src/sampleForModule3.ts +2 -0
- package/tsconfig.json +70 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Importer } from '../src/analyze';
|
|
2
|
+
import { ParameterizableClass, ParameterizableInterface } from '../src/lib/famix/src/model/famix';
|
|
3
|
+
|
|
4
|
+
const importer = new Importer();
|
|
5
|
+
|
|
6
|
+
const fmxRep = importer.famixRepFromSource("genericClassInheritsInterface",
|
|
7
|
+
'interface MyDaoInterface<T> {}\n\
|
|
8
|
+
\n\
|
|
9
|
+
class MyDao<T> implements MyDaoInterface<T> {}\n\
|
|
10
|
+
');
|
|
11
|
+
|
|
12
|
+
describe('Tests for generic class inherits interface', () => {
|
|
13
|
+
|
|
14
|
+
it("should parse generics", () => {
|
|
15
|
+
expect(fmxRep).toBeTruthy();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it("should contain one generic class and one generic interface", () => {
|
|
19
|
+
expect(fmxRep._getAllEntitiesWithType("ParameterizableClass").size).toBe(1);
|
|
20
|
+
expect(fmxRep._getAllEntitiesWithType("ParameterizableInterface").size).toBe(1);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("should contain a generic class MyDao that implements a generic interface MyDaoInterface", () => {
|
|
24
|
+
const cList = Array.from(fmxRep._getAllEntitiesWithType("ParameterizableClass") as Set<ParameterizableClass>);
|
|
25
|
+
expect(cList).toBeTruthy();
|
|
26
|
+
const myDao = cList.find(p => p.getName() === "MyDao");
|
|
27
|
+
expect(myDao).toBeTruthy();
|
|
28
|
+
const iList = Array.from(fmxRep._getAllEntitiesWithType("ParameterizableInterface") as Set<ParameterizableInterface>);
|
|
29
|
+
expect(iList).toBeTruthy();
|
|
30
|
+
const myDaoInterface = iList.find(p => p.getName() === "MyDaoInterface");
|
|
31
|
+
expect(myDaoInterface).toBeTruthy();
|
|
32
|
+
if (myDao) {
|
|
33
|
+
expect(myDao.getSubInheritances().size).toBe(0);
|
|
34
|
+
expect(myDao.getSuperInheritances().size).toBe(1);
|
|
35
|
+
const theInheritance = (Array.from(myDao.getSuperInheritances())[0]);
|
|
36
|
+
expect(theInheritance.getSuperclass()).toBeTruthy();
|
|
37
|
+
expect(theInheritance.getSuperclass()).toBe(myDaoInterface);
|
|
38
|
+
}
|
|
39
|
+
if (myDaoInterface) {
|
|
40
|
+
expect(myDaoInterface.getSubInheritances().size).toBe(1);
|
|
41
|
+
expect(myDaoInterface.getSuperInheritances().size).toBe(0);
|
|
42
|
+
const theInheritance = (Array.from(myDaoInterface.getSubInheritances())[0]);
|
|
43
|
+
expect(theInheritance.getSubclass()).toBeTruthy();
|
|
44
|
+
expect(theInheritance.getSubclass()).toBe(myDao);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Importer } from '../src/analyze';
|
|
2
|
+
import { ParameterizableInterface, TypeParameter } from '../src/lib/famix/src/model/famix';
|
|
3
|
+
|
|
4
|
+
const importer = new Importer();
|
|
5
|
+
|
|
6
|
+
const fmxRep = importer.famixRepFromSource("genericInterface",
|
|
7
|
+
'interface MyInterface<T> {\n\
|
|
8
|
+
myProperty;\n\
|
|
9
|
+
myMethod();\n\
|
|
10
|
+
}\n\
|
|
11
|
+
');
|
|
12
|
+
|
|
13
|
+
describe('Tests for generic interface', () => {
|
|
14
|
+
|
|
15
|
+
it("should parse generics", () => {
|
|
16
|
+
expect(fmxRep).toBeTruthy();
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it("should contain one generic interface", () => {
|
|
20
|
+
expect(fmxRep._getAllEntitiesWithType("ParameterizableInterface").size).toBe(1);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("should contain a generic interface MyInterface", () => {
|
|
24
|
+
const listOfNames = Array.from(fmxRep._getAllEntitiesWithType("ParameterizableInterface")).map(e => (e as ParameterizableInterface).getName());
|
|
25
|
+
expect(listOfNames).toContain("MyInterface");
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("should contain a generic interface MyInterface with a type parameter T", () => {
|
|
29
|
+
const pList = Array.from(fmxRep._getAllEntitiesWithType("ParameterizableInterface") as Set<ParameterizableInterface>);
|
|
30
|
+
expect(pList).toBeTruthy();
|
|
31
|
+
const MyInterface = pList.find(p => p.getName() === "MyInterface");
|
|
32
|
+
expect(MyInterface).toBeTruthy();
|
|
33
|
+
expect(MyInterface?.getTypeParameters().size).toBe(1);
|
|
34
|
+
if (MyInterface) {
|
|
35
|
+
expect((Array.from(MyInterface.getTypeParameters())[0] as TypeParameter).getName()).toBe("T");
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
});
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Importer } from '../src/analyze';
|
|
2
|
+
import { Class } from "../src/lib/famix/src/model/famix/class";
|
|
3
|
+
import { Method } from "../src/lib/famix/src/model/famix/method";
|
|
4
|
+
import { Parameter } from "../src/lib/famix/src/model/famix/parameter";
|
|
5
|
+
|
|
6
|
+
const importer = new Importer();
|
|
7
|
+
|
|
8
|
+
const fmxRep = importer.famixRepFromSource("genericMethod",
|
|
9
|
+
'class AA {\n\
|
|
10
|
+
public i<T> (j: T): void {}\n\
|
|
11
|
+
}\n\
|
|
12
|
+
');
|
|
13
|
+
|
|
14
|
+
describe('Tests for generics', () => {
|
|
15
|
+
|
|
16
|
+
const theClass = fmxRep._getFamixClass("AA");
|
|
17
|
+
|
|
18
|
+
it("should parse generics", () => {
|
|
19
|
+
expect(fmxRep).toBeTruthy();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("should contain one class", () => {
|
|
23
|
+
expect(fmxRep._getAllEntitiesWithType("Class").size).toBe(1);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("should contain a class AA", () => {
|
|
27
|
+
const listOfNames = Array.from(fmxRep._getAllEntitiesWithType("Class")).map(e => (e as Class).getName());
|
|
28
|
+
expect(listOfNames).toContain("AA");
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("should not be an abstract class", () => {
|
|
32
|
+
expect(theClass).toBeTruthy();
|
|
33
|
+
if (theClass) expect(theClass.getIsAbstract()).toBe(false);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("should contain a generic method i for class AA with type parameter T", () => {
|
|
37
|
+
const cList = Array.from(fmxRep._getAllEntitiesWithType("Class") as Set<Class>);
|
|
38
|
+
expect(cList).toBeTruthy();
|
|
39
|
+
const AA = cList.find(c => c.getName() === "AA");
|
|
40
|
+
const mList = Array.from(AA?.getMethods() as Set<Method>);
|
|
41
|
+
const i = mList?.find(m => m.getName() === "i");
|
|
42
|
+
expect(i).toBeTruthy();
|
|
43
|
+
expect(i?.getDeclaredType().getName()).toBe("void");
|
|
44
|
+
expect(i?.getParameters().size).toBe(1);
|
|
45
|
+
const pList = Array.from(i?.getParameters() as Set<Parameter>);
|
|
46
|
+
const j = pList?.find(p => p.getName() === "j");
|
|
47
|
+
expect(j).toBeTruthy();
|
|
48
|
+
expect(j?.getDeclaredType().getName()).toBe("T");
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it("should contain a public method i", () => {
|
|
52
|
+
const pList = Array.from(fmxRep._getAllEntitiesWithType("Method") as Set<Method>);
|
|
53
|
+
expect(pList).toBeTruthy();
|
|
54
|
+
const i = pList.find(p => p.getName() === "i");
|
|
55
|
+
expect(i).toBeTruthy();
|
|
56
|
+
if (i) {
|
|
57
|
+
expect(i.getKind()).toBe(undefined);
|
|
58
|
+
expect(i.getIsAbstract()).toBe(false);
|
|
59
|
+
expect(i.getIsClassSide()).toBe(false);
|
|
60
|
+
expect(i.getIsPrivate()).toBe(false);
|
|
61
|
+
expect(i.getIsProtected()).toBe(false);
|
|
62
|
+
expect(i.getIsPublic()).toBe(true);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
});
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Importer } from '../src/analyze';
|
|
2
|
+
import { Method } from "../src/lib/famix/src/model/famix/method";
|
|
3
|
+
import { Variable } from "../src/lib/famix/src/model/famix/variable";
|
|
4
|
+
import { Invocation } from "../src/lib/famix/src/model/famix/invocation";
|
|
5
|
+
|
|
6
|
+
const importer = new Importer();
|
|
7
|
+
|
|
8
|
+
const fmxRep = importer.famixRepFromSource("genericWithInvocation",
|
|
9
|
+
'class AA {\n\
|
|
10
|
+
public i<T> (j: T): void {}\n\
|
|
11
|
+
}\n\
|
|
12
|
+
\n\
|
|
13
|
+
const x = new AA();\n\
|
|
14
|
+
x.i<string>("ok");\n\
|
|
15
|
+
');
|
|
16
|
+
|
|
17
|
+
describe('Tests for generics', () => {
|
|
18
|
+
|
|
19
|
+
const theMethod = fmxRep._getFamixMethod("i") as Method;
|
|
20
|
+
|
|
21
|
+
it("should parse generics", () => {
|
|
22
|
+
expect(fmxRep).toBeTruthy();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it("should contain a variable x instance of AA", () => {
|
|
26
|
+
const pList = Array.from(fmxRep._getAllEntitiesWithType("Variable") as Set<Variable>);
|
|
27
|
+
expect(pList).toBeTruthy();
|
|
28
|
+
const x = pList.find(p => p.getName() === "x");
|
|
29
|
+
expect(x).toBeTruthy();
|
|
30
|
+
expect(x?.getDeclaredType().getName()).toBe("AA");
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it("should contain an invocation for i", () => {
|
|
34
|
+
expect(theMethod).toBeTruthy();
|
|
35
|
+
const invocations = Array.from(fmxRep._getAllEntitiesWithType("Invocation"));
|
|
36
|
+
expect(invocations).toBeTruthy();
|
|
37
|
+
expect(invocations.length).toBe(1);
|
|
38
|
+
const candidates = invocations.filter(i => {
|
|
39
|
+
const invocation = i as Invocation;
|
|
40
|
+
return invocation.getCandidates().has(theMethod);
|
|
41
|
+
});
|
|
42
|
+
expect(candidates).toHaveLength(1);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("should contain an invocation for i with a sender 'genericWithInvocation.ts'", () => {
|
|
46
|
+
expect(theMethod).toBeTruthy();
|
|
47
|
+
const invocations = Array.from(fmxRep._getAllEntitiesWithType("Invocation"));
|
|
48
|
+
expect(invocations).toBeTruthy();
|
|
49
|
+
expect(invocations.length).toBe(1);
|
|
50
|
+
expect((invocations[0] as Invocation).getSender()).toBeTruthy();
|
|
51
|
+
expect((invocations[0] as Invocation).getSender()).toBe(fmxRep._getFamixFile("genericWithInvocation.ts"));
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("should contain an invocation for i with a receiver 'AA'", () => {
|
|
55
|
+
expect(theMethod).toBeTruthy();
|
|
56
|
+
const invocations = Array.from(fmxRep._getAllEntitiesWithType("Invocation"));
|
|
57
|
+
expect(invocations).toBeTruthy();
|
|
58
|
+
expect(invocations.length).toBe(1);
|
|
59
|
+
expect((invocations[0] as Invocation).getReceiver()).toBeTruthy();
|
|
60
|
+
expect((invocations[0] as Invocation).getReceiver()).toBe(fmxRep._getFamixClass("AA"));
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it("should contain an invocation for i with a signature 'public i<T> (j: T): void'", () => {
|
|
64
|
+
expect(theMethod).toBeTruthy();
|
|
65
|
+
const invocations = Array.from(fmxRep._getAllEntitiesWithType("Invocation"));
|
|
66
|
+
expect(invocations).toBeTruthy();
|
|
67
|
+
expect(invocations.length).toBe(1);
|
|
68
|
+
expect((invocations[0] as Invocation).getSignature()).toBeTruthy();
|
|
69
|
+
expect((invocations[0] as Invocation).getSignature()).toBe('public i<T> (j: T): void');
|
|
70
|
+
});
|
|
71
|
+
});
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { Importer } from '../src/analyze';
|
|
2
|
+
import { ParameterizableClass, ParameterizableInterface, TypeParameter } from '../src/lib/famix/src/model/famix';
|
|
3
|
+
|
|
4
|
+
const importer = new Importer();
|
|
5
|
+
|
|
6
|
+
const fmxRep = importer.famixRepFromSource("generics",
|
|
7
|
+
'interface MyDaoInterface<T> {}\n\
|
|
8
|
+
\n\
|
|
9
|
+
class MyDao<T> implements MyDaoInterface<T> {}\n\
|
|
10
|
+
');
|
|
11
|
+
|
|
12
|
+
describe('Generics', () => {
|
|
13
|
+
|
|
14
|
+
it("should parse generics", () => {
|
|
15
|
+
expect(fmxRep).toBeTruthy();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it("should contain one generic class and one generic interface", () => {
|
|
19
|
+
expect(fmxRep._getAllEntitiesWithType("ParameterizableClass").size).toBe(1);
|
|
20
|
+
expect(fmxRep._getAllEntitiesWithType("ParameterizableInterface").size).toBe(1);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("should contain a generic class MyDao and a generic interface MyDaoInterface", () => {
|
|
24
|
+
const listOfNames = Array.from(fmxRep._getAllEntitiesWithType("ParameterizableClass")).map(e => (e as ParameterizableClass).getName());
|
|
25
|
+
expect(listOfNames).toContain("MyDao");
|
|
26
|
+
const listOfNames2 = Array.from(fmxRep._getAllEntitiesWithType("ParameterizableInterface")).map(e => (e as ParameterizableInterface).getName());
|
|
27
|
+
expect(listOfNames2).toContain("MyDaoInterface");
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it("should contain a generic class MyDao with a type parameter T", () => {
|
|
31
|
+
const pList = Array.from(fmxRep._getAllEntitiesWithType("ParameterizableClass") as Set<ParameterizableClass>);
|
|
32
|
+
expect(pList).toBeTruthy();
|
|
33
|
+
const myDao = pList.find(p => p.getName() === "MyDao");
|
|
34
|
+
expect(myDao).toBeTruthy();
|
|
35
|
+
expect(myDao?.getTypeParameters().size).toBe(1);
|
|
36
|
+
if (myDao) {
|
|
37
|
+
expect((Array.from(myDao.getTypeParameters())[0] as TypeParameter).getName()).toBe("T");
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("should contain a generic interface MyDaoInterface with a type parameter T", () => {
|
|
42
|
+
const pList = Array.from(fmxRep._getAllEntitiesWithType("ParameterizableInterface") as Set<ParameterizableInterface>);
|
|
43
|
+
expect(pList).toBeTruthy();
|
|
44
|
+
const myDaoInterface = pList.find(p => p.getName() === "MyDaoInterface");
|
|
45
|
+
expect(myDaoInterface).toBeTruthy();
|
|
46
|
+
expect(myDaoInterface?.getTypeParameters().size).toBe(1);
|
|
47
|
+
if (myDaoInterface) {
|
|
48
|
+
expect((Array.from(myDaoInterface.getTypeParameters())[0] as TypeParameter).getName()).toBe("T");
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it("should contain a generic class MyDao that implements a generic interface MyDaoInterface", () => {
|
|
53
|
+
const cList = Array.from(fmxRep._getAllEntitiesWithType("ParameterizableClass") as Set<ParameterizableClass>);
|
|
54
|
+
expect(cList).toBeTruthy();
|
|
55
|
+
const myDao = cList.find(p => p.getName() === "MyDao");
|
|
56
|
+
expect(myDao).toBeTruthy();
|
|
57
|
+
const iList = Array.from(fmxRep._getAllEntitiesWithType("ParameterizableInterface") as Set<ParameterizableInterface>);
|
|
58
|
+
expect(iList).toBeTruthy();
|
|
59
|
+
const myDaoInterface = iList.find(p => p.getName() === "MyDaoInterface");
|
|
60
|
+
expect(myDaoInterface).toBeTruthy();
|
|
61
|
+
if (myDao) {
|
|
62
|
+
expect(myDao.getSuperInheritances().size).toBe(1);
|
|
63
|
+
const theInheritance = (Array.from(myDao.getSuperInheritances())[0]);
|
|
64
|
+
expect(theInheritance.getSuperclass()).toBeTruthy();
|
|
65
|
+
expect(theInheritance.getSuperclass()).toBe(myDaoInterface);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Importer } from '../src/analyze';
|
|
2
|
+
|
|
3
|
+
const importer = new Importer();
|
|
4
|
+
|
|
5
|
+
const fmxRep = importer.famixRepFromSource("inheritance",
|
|
6
|
+
'class Animal {}\n\
|
|
7
|
+
class Fish extends Animal {}\n\
|
|
8
|
+
interface Flyable {}\n\
|
|
9
|
+
class Bird extends Animal implements Flyable {}\n\
|
|
10
|
+
');
|
|
11
|
+
|
|
12
|
+
describe('Inheritance', () => {
|
|
13
|
+
|
|
14
|
+
const jsonOutput = fmxRep.getJSON();
|
|
15
|
+
const parsedModel = JSON.parse(jsonOutput);
|
|
16
|
+
const idToElementMap = fmxRep._initMapFromModel(jsonOutput);
|
|
17
|
+
|
|
18
|
+
it("should contain a Fish class who has a superclass Animal", () => {
|
|
19
|
+
const fishCls = parsedModel.filter(el => (el.FM3 === "FamixTypeScript.Class" && el.name === "Fish"))[0];
|
|
20
|
+
const superInheritance = idToElementMap.get(fishCls.superInheritances[0].ref) as any;
|
|
21
|
+
expect((idToElementMap.get(superInheritance.superclass.ref) as any).name).toBe("Animal");
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("should contain an Animal class who has a subclass Fish", () => {
|
|
25
|
+
const animalCls = parsedModel.filter(el => (el.FM3 === "FamixTypeScript.Class" && el.name === "Animal"))[0];
|
|
26
|
+
const subInheritance = idToElementMap.get(animalCls.subInheritances[0].ref) as any;
|
|
27
|
+
expect((idToElementMap.get(subInheritance.subclass.ref) as any).name).toBe("Fish");
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it("should contain a Flyable interface", () => {
|
|
31
|
+
const flyableInterface = parsedModel.filter(el => (el.FM3 === "FamixTypeScript.Interface" && el.name === "Flyable"))[0];
|
|
32
|
+
expect(flyableInterface).toBeTruthy();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("should contain a Bird class who has a superclass Animal and implements a Flyable interface", () => {
|
|
36
|
+
const animalCls = parsedModel.filter(el => (el.FM3 === "FamixTypeScript.Class" && el.name === "Animal"))[0];
|
|
37
|
+
expect(animalCls).toBeTruthy();
|
|
38
|
+
const flyableInterface = parsedModel.filter(el => (el.FM3 === "FamixTypeScript.Interface" && el.name === "Flyable"))[0];
|
|
39
|
+
expect(flyableInterface).toBeTruthy();
|
|
40
|
+
const birdCls = parsedModel.filter(el => (el.FM3 === "FamixTypeScript.Class" && el.name === "Bird"))[0];
|
|
41
|
+
expect(birdCls).toBeTruthy();
|
|
42
|
+
// extends Animal, implements Flyable
|
|
43
|
+
const birdSuperInheritances = birdCls.superInheritances;
|
|
44
|
+
expect(birdSuperInheritances.length).toBe(2);
|
|
45
|
+
const extendsRef = birdSuperInheritances.filter(si => (si.ref === animalCls.ref));
|
|
46
|
+
expect(extendsRef).toBeTruthy();
|
|
47
|
+
const interfaceRef = birdSuperInheritances.filter(si => (si.ref === flyableInterface.ref));
|
|
48
|
+
expect(interfaceRef).toBeTruthy();
|
|
49
|
+
});
|
|
50
|
+
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Importer } from '../src/analyze';
|
|
2
|
+
import { Interface } from '../src/lib/famix/src/model/famix';
|
|
3
|
+
|
|
4
|
+
const importer = new Importer();
|
|
5
|
+
|
|
6
|
+
const fmxRep = importer.famixRepFromSource("interfaceInheritsInterface",
|
|
7
|
+
'interface MyInterface1 {}\n\
|
|
8
|
+
\n\
|
|
9
|
+
interface MyInterface2 extends MyInterface1 {}\n\
|
|
10
|
+
');
|
|
11
|
+
|
|
12
|
+
describe('Tests for interface inherits interface', () => {
|
|
13
|
+
|
|
14
|
+
it("should contain two interfaces", () => {
|
|
15
|
+
expect(fmxRep._getAllEntitiesWithType("Interface").size).toBe(2);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it("should contain an interface MyInterface2 that extends an interface MyInterface1", () => {
|
|
19
|
+
const cList = Array.from(fmxRep._getAllEntitiesWithType("Interface") as Set<Interface>);
|
|
20
|
+
expect(cList).toBeTruthy();
|
|
21
|
+
const myInterface1 = cList.find(p => p.getName() === "MyInterface1");
|
|
22
|
+
expect(myInterface1).toBeTruthy();
|
|
23
|
+
const myInterface2 = cList.find(p => p.getName() === "MyInterface2");
|
|
24
|
+
expect(myInterface2).toBeTruthy();
|
|
25
|
+
if (myInterface2) {
|
|
26
|
+
expect(myInterface2.getSubInheritances().size).toBe(0);
|
|
27
|
+
expect(myInterface2.getSuperInheritances().size).toBe(1);
|
|
28
|
+
const theInheritance = (Array.from(myInterface2.getSuperInheritances())[0]);
|
|
29
|
+
expect(theInheritance.getSuperclass()).toBeTruthy();
|
|
30
|
+
expect(theInheritance.getSuperclass()).toBe(myInterface1);
|
|
31
|
+
}
|
|
32
|
+
if (myInterface1) {
|
|
33
|
+
expect(myInterface1.getSubInheritances().size).toBe(1);
|
|
34
|
+
expect(myInterface1.getSuperInheritances().size).toBe(0);
|
|
35
|
+
const theInheritance = (Array.from(myInterface1.getSubInheritances())[0]);
|
|
36
|
+
expect(theInheritance.getSubclass()).toBeTruthy();
|
|
37
|
+
expect(theInheritance.getSubclass()).toBe(myInterface2);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Importer } from '../src/analyze';
|
|
2
|
+
import { Interface } from '../src/lib/famix/src/model/famix';
|
|
3
|
+
|
|
4
|
+
const importer = new Importer();
|
|
5
|
+
|
|
6
|
+
const fmxRep = importer.famixRepFromSource("interfaceInheritsUndefinedInterface",
|
|
7
|
+
'import {FileSystemHost} from "ts-morph";\n\
|
|
8
|
+
\n\
|
|
9
|
+
interface MyInterface extends FileSystemHost {}\n\
|
|
10
|
+
');
|
|
11
|
+
|
|
12
|
+
describe('Tests for interface inherits undefined interface', () => {
|
|
13
|
+
|
|
14
|
+
it("should contain two interfaces", () => {
|
|
15
|
+
expect(fmxRep._getAllEntitiesWithType("Interface").size).toBe(2);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it("should contain an interface MyInterface that extends an interface FileSystemHost", () => {
|
|
19
|
+
const cList = Array.from(fmxRep._getAllEntitiesWithType("Interface") as Set<Interface>);
|
|
20
|
+
expect(cList).toBeTruthy();
|
|
21
|
+
const myInterface1 = cList.find(p => p.getName() === "FileSystemHost");
|
|
22
|
+
expect(myInterface1).toBeTruthy();
|
|
23
|
+
expect(myInterface1?.getIsStub()).toBe(true);
|
|
24
|
+
const myInterface2 = cList.find(p => p.getName() === "MyInterface");
|
|
25
|
+
expect(myInterface2).toBeTruthy();
|
|
26
|
+
if (myInterface2) {
|
|
27
|
+
expect(myInterface2.getSubInheritances().size).toBe(0);
|
|
28
|
+
expect(myInterface2.getSuperInheritances().size).toBe(1);
|
|
29
|
+
const theInheritance = (Array.from(myInterface2.getSuperInheritances())[0]);
|
|
30
|
+
expect(theInheritance.getSuperclass()).toBeTruthy();
|
|
31
|
+
expect(theInheritance.getSuperclass()).toBe(myInterface1);
|
|
32
|
+
}
|
|
33
|
+
if (myInterface1) {
|
|
34
|
+
expect(myInterface1.getSubInheritances().size).toBe(1);
|
|
35
|
+
expect(myInterface1.getSuperInheritances().size).toBe(0);
|
|
36
|
+
const theInheritance = (Array.from(myInterface1.getSubInheritances())[0]);
|
|
37
|
+
expect(theInheritance.getSubclass()).toBeTruthy();
|
|
38
|
+
expect(theInheritance.getSubclass()).toBe(myInterface2);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
});
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { Importer } from '../src/analyze';
|
|
2
|
+
import { Class } from "../src/lib/famix/src/model/famix/class";
|
|
3
|
+
import { Method } from "../src/lib/famix/src/model/famix/method";
|
|
4
|
+
import { Invocation } from "../src/lib/famix/src/model/famix/invocation";
|
|
5
|
+
|
|
6
|
+
const importer = new Importer();
|
|
7
|
+
|
|
8
|
+
const fmxRep = importer.famixRepFromSource("invocation",
|
|
9
|
+
'class A {\n\
|
|
10
|
+
public x(): void {}\n\
|
|
11
|
+
}\n\
|
|
12
|
+
\n\
|
|
13
|
+
class B {\n\
|
|
14
|
+
public y(): void {\n\
|
|
15
|
+
new A().x();\n\
|
|
16
|
+
}\n\
|
|
17
|
+
}\n\
|
|
18
|
+
');
|
|
19
|
+
|
|
20
|
+
describe('Tests for invocation', () => {
|
|
21
|
+
|
|
22
|
+
const theMethod = fmxRep._getFamixMethod("x") as Method;
|
|
23
|
+
|
|
24
|
+
it("should contain two class", () => {
|
|
25
|
+
expect(fmxRep._getAllEntitiesWithType("Class").size).toBe(2);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("should contain a class A and a class B", () => {
|
|
29
|
+
const listOfNames = Array.from(fmxRep._getAllEntitiesWithType("Class")).map(e => (e as Class).getName());
|
|
30
|
+
expect(listOfNames).toContain("A");
|
|
31
|
+
expect(listOfNames).toContain("B");
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("should contain a method x for class A", () => {
|
|
35
|
+
const cList = Array.from(fmxRep._getAllEntitiesWithType("Class") as Set<Class>);
|
|
36
|
+
expect(cList).toBeTruthy();
|
|
37
|
+
const A = cList.find(c => c.getName() === "A");
|
|
38
|
+
const mList = Array.from(A?.getMethods() as Set<Method>);
|
|
39
|
+
const x = mList?.find(m => m.getName() === "x");
|
|
40
|
+
expect(x).toBeTruthy();
|
|
41
|
+
expect(x?.getDeclaredType().getName()).toBe("void");
|
|
42
|
+
expect(x?.getParameters().size).toBe(0);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("should contain a method y for class B", () => {
|
|
46
|
+
const cList = Array.from(fmxRep._getAllEntitiesWithType("Class") as Set<Class>);
|
|
47
|
+
expect(cList).toBeTruthy();
|
|
48
|
+
const B = cList.find(c => c.getName() === "B");
|
|
49
|
+
const mList = Array.from(B?.getMethods() as Set<Method>);
|
|
50
|
+
const y = mList?.find(m => m.getName() === "y");
|
|
51
|
+
expect(y).toBeTruthy();
|
|
52
|
+
expect(y?.getDeclaredType().getName()).toBe("void");
|
|
53
|
+
expect(y?.getParameters().size).toBe(0);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it("should contain an invocation for x", () => {
|
|
57
|
+
expect(theMethod).toBeTruthy();
|
|
58
|
+
const invocations = Array.from(fmxRep._getAllEntitiesWithType("Invocation"));
|
|
59
|
+
expect(invocations).toBeTruthy();
|
|
60
|
+
expect(invocations.length).toBe(1);
|
|
61
|
+
const candidates = invocations.filter(i => {
|
|
62
|
+
const invocation = i as Invocation;
|
|
63
|
+
return invocation.getCandidates().has(theMethod);
|
|
64
|
+
});
|
|
65
|
+
expect(candidates).toHaveLength(1);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it("should contain an invocation for x with a sender 'y'", () => {
|
|
69
|
+
expect(theMethod).toBeTruthy();
|
|
70
|
+
const invocations = Array.from(fmxRep._getAllEntitiesWithType("Invocation"));
|
|
71
|
+
expect(invocations).toBeTruthy();
|
|
72
|
+
expect(invocations.length).toBe(1);
|
|
73
|
+
expect((invocations[0] as Invocation).getSender()).toBeTruthy();
|
|
74
|
+
expect((invocations[0] as Invocation).getSender()).toBe(fmxRep._getFamixMethod("y"));
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("should contain an invocation for x with a receiver 'A'", () => {
|
|
78
|
+
expect(theMethod).toBeTruthy();
|
|
79
|
+
const invocations = Array.from(fmxRep._getAllEntitiesWithType("Invocation"));
|
|
80
|
+
expect(invocations).toBeTruthy();
|
|
81
|
+
expect(invocations.length).toBe(1);
|
|
82
|
+
expect((invocations[0] as Invocation).getReceiver()).toBeTruthy();
|
|
83
|
+
expect((invocations[0] as Invocation).getReceiver()).toBe(fmxRep._getFamixClass("A"));
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("should contain an invocation for x with a signature 'public x(): void'", () => {
|
|
87
|
+
expect(theMethod).toBeTruthy();
|
|
88
|
+
const invocations = Array.from(fmxRep._getAllEntitiesWithType("Invocation"));
|
|
89
|
+
expect(invocations).toBeTruthy();
|
|
90
|
+
expect(invocations.length).toBe(1);
|
|
91
|
+
expect((invocations[0] as Invocation).getSignature()).toBeTruthy();
|
|
92
|
+
expect((invocations[0] as Invocation).getSignature()).toBe('public x(): void');
|
|
93
|
+
});
|
|
94
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Importer } from '../src/analyze';
|
|
2
|
+
import { Function } from "../src/lib/famix/src/model/famix/function";
|
|
3
|
+
import { Variable } from "../src/lib/famix/src/model/famix/variable";
|
|
4
|
+
import { Invocation } from "../src/lib/famix/src/model/famix/invocation";
|
|
5
|
+
|
|
6
|
+
const importer = new Importer();
|
|
7
|
+
|
|
8
|
+
const fmxRep = importer.famixRepFromSource("invocationWithFunction",
|
|
9
|
+
'function func(): void {}\n\
|
|
10
|
+
\n\
|
|
11
|
+
const x1 = func();\n\
|
|
12
|
+
');
|
|
13
|
+
|
|
14
|
+
describe('Tests for invocation with function', () => {
|
|
15
|
+
|
|
16
|
+
it("should contain a variable 'x1'", () => {
|
|
17
|
+
const pList = Array.from(fmxRep._getAllEntitiesWithType("Variable") as Set<Variable>);
|
|
18
|
+
expect(pList).toBeTruthy();
|
|
19
|
+
const x1 = pList.find(p => p.getName() === "x1");
|
|
20
|
+
expect(x1).toBeTruthy();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const theFunction = fmxRep._getFamixFunction("func") as Function;
|
|
24
|
+
const invocations = Array.from(fmxRep._getAllEntitiesWithType("Invocation"));
|
|
25
|
+
|
|
26
|
+
it("should contain one invocation", () => {
|
|
27
|
+
expect(invocations).toBeTruthy();
|
|
28
|
+
expect(invocations.length).toBe(1);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("should contain an invocation for 'func'", () => {
|
|
32
|
+
expect((invocations[0] as Invocation).getCandidates().has(theFunction));
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("should contain an invocation with a sender 'invocationWithFunction.ts'", () => {
|
|
36
|
+
expect((invocations[0] as Invocation).getSender()).toBe(fmxRep._getFamixFile("invocationWithFunction.ts"));
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it("should contain an invocation with a receiver 'invocationWithFunction.ts'", () => {
|
|
40
|
+
expect((invocations[0] as Invocation).getReceiver()).toBe(fmxRep._getFamixFile("invocationWithFunction.ts"));
|
|
41
|
+
});
|
|
42
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Importer } from '../src/analyze';
|
|
2
|
+
import { Method } from "../src/lib/famix/src/model/famix/method";
|
|
3
|
+
import { Variable } from "../src/lib/famix/src/model/famix/variable";
|
|
4
|
+
import { Invocation } from "../src/lib/famix/src/model/famix/invocation";
|
|
5
|
+
|
|
6
|
+
const importer = new Importer();
|
|
7
|
+
|
|
8
|
+
const fmxRep = importer.famixRepFromSource("invocationWithVariable",
|
|
9
|
+
'class AAA {\n\
|
|
10
|
+
public method(): void {}\n\
|
|
11
|
+
}\n\
|
|
12
|
+
\n\
|
|
13
|
+
const x1 = new AAA();\n\
|
|
14
|
+
x1.method();\n\
|
|
15
|
+
');
|
|
16
|
+
|
|
17
|
+
describe('Tests for invocation with variable', () => {
|
|
18
|
+
|
|
19
|
+
it("should contain a variable 'x1' instance of 'AAA'", () => {
|
|
20
|
+
const pList = Array.from(fmxRep._getAllEntitiesWithType("Variable") as Set<Variable>);
|
|
21
|
+
expect(pList).toBeTruthy();
|
|
22
|
+
const x1 = pList.find(p => p.getName() === "x1");
|
|
23
|
+
expect(x1).toBeTruthy();
|
|
24
|
+
expect(x1?.getDeclaredType().getName()).toBe("AAA");
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const theMethod = fmxRep._getFamixMethod("method") as Method;
|
|
28
|
+
const invocations = Array.from(fmxRep._getAllEntitiesWithType("Invocation"));
|
|
29
|
+
|
|
30
|
+
it("should contain one invocation", () => {
|
|
31
|
+
expect(invocations).toBeTruthy();
|
|
32
|
+
expect(invocations.length).toBe(1);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("should contain an invocation for 'method'", () => {
|
|
36
|
+
expect((invocations[0] as Invocation).getCandidates().has(theMethod));
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it("should contain an invocation with a sender 'invocationWithVariable.ts'", () => {
|
|
40
|
+
expect((invocations[0] as Invocation).getSender()).toBe(fmxRep._getFamixFile("invocationWithVariable.ts"));
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it("should contain an invocation with a receiver 'AAA'", () => {
|
|
44
|
+
expect((invocations[0] as Invocation).getReceiver()).toBe(fmxRep._getFamixClass("AAA"));
|
|
45
|
+
});
|
|
46
|
+
});
|