@specs-feup/clava-misra 1.0.0

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.
Files changed (65) hide show
  1. package/CxxSources/lib.cpp +3 -0
  2. package/CxxSources/lib.h +8 -0
  3. package/CxxSources/main.cpp +40 -0
  4. package/README.md +32 -0
  5. package/TODO.md +1 -0
  6. package/consumer_order.txt +2 -0
  7. package/enum_integer_type.txt +0 -0
  8. package/is_temporary.txt +0 -0
  9. package/jest.config.js +25 -0
  10. package/omp.txt +0 -0
  11. package/package.json +23 -0
  12. package/src/foo.ts +6 -0
  13. package/src/main.ts +36 -0
  14. package/src/misra/MISRAAnalyser.ts +43 -0
  15. package/src/misra/MISRAPass.ts +85 -0
  16. package/src/misra/MISRAPassResult.ts +20 -0
  17. package/src/misra/MISRAReporter.ts +57 -0
  18. package/src/misra/passes/S10_EssentialTypePass.ts +395 -0
  19. package/src/misra/passes/S12_ExpressionPass.ts +86 -0
  20. package/src/misra/passes/S13_SideEffectPass.ts +121 -0
  21. package/src/misra/passes/S15_ControlFlowPass.ts +108 -0
  22. package/src/misra/passes/S16_SwitchStatementPass.ts +168 -0
  23. package/src/misra/passes/S17_FunctionPass.ts +43 -0
  24. package/src/misra/passes/S18_PointersArraysPass.ts +126 -0
  25. package/src/misra/passes/S19_OverlappingStoragePass.ts +27 -0
  26. package/src/misra/passes/S21_StandardLibPass.ts +92 -0
  27. package/src/misra/passes/S3_CommentPass.ts +40 -0
  28. package/src/misra/passes/S5_IdentifierPass.ts +66 -0
  29. package/src/misra/passes/S6_TypePass.ts +32 -0
  30. package/src/misra/passes/S7_LiteralsConstantsPass.ts +80 -0
  31. package/src/misra/passes/S8_DeclDefPass.ts +138 -0
  32. package/src/misra/sections/Section10_EssentialTypeModel.ts +377 -0
  33. package/src/misra/sections/Section11_PointerTypeConversions.ts +103 -0
  34. package/src/misra/sections/Section12_Expressions.ts +80 -0
  35. package/src/misra/sections/Section13_SideEffects.ts +100 -0
  36. package/src/misra/sections/Section14_ControlStmtExprs.ts +27 -0
  37. package/src/misra/sections/Section15_ControlFlow.ts +114 -0
  38. package/src/misra/sections/Section16_SwitchStatements.ts +154 -0
  39. package/src/misra/sections/Section17_Functions.ts +33 -0
  40. package/src/misra/sections/Section18_PointersAndArrays.ts +108 -0
  41. package/src/misra/sections/Section19_OverlappingStorage.ts +18 -0
  42. package/src/misra/sections/Section20_PreprocessingDirectives.ts +22 -0
  43. package/src/misra/sections/Section21_StandardLibraries.ts +65 -0
  44. package/src/misra/sections/Section2_UnusedCode.ts +47 -0
  45. package/src/misra/sections/Section3_Comments.ts +23 -0
  46. package/src/misra/sections/Section5_Identifiers.ts +149 -0
  47. package/src/misra/sections/Section6_Types.ts +26 -0
  48. package/src/misra/sections/Section7_LiteralsConstants.ts +76 -0
  49. package/src/misra/sections/Section8_DeclarationsDefinitions.ts +133 -0
  50. package/src/misra/tests/S10_EssentialTypes.test.ts +253 -0
  51. package/src/misra/tests/S12_Expressions.test.ts +43 -0
  52. package/src/misra/tests/S13_SideEffects.test.ts +77 -0
  53. package/src/misra/tests/S15_ControlFlow.test.ts +144 -0
  54. package/src/misra/tests/S16_SwitchStatements.test.ts +164 -0
  55. package/src/misra/tests/S17_Functions.test.ts +46 -0
  56. package/src/misra/tests/S18_PointersArrays.test.ts +167 -0
  57. package/src/misra/tests/S19_OverlappingStorage.test.ts +38 -0
  58. package/src/misra/tests/S3_Comments.test.ts +36 -0
  59. package/src/misra/tests/S6_Types.test.ts +36 -0
  60. package/src/misra/tests/S7_LiteralsConstants.test.ts +48 -0
  61. package/src/misra/tests/utils.ts +47 -0
  62. package/tsconfig.jest.json +5 -0
  63. package/tsconfig.json +18 -0
  64. package/typedoc.config.js +6 -0
  65. package/types_with_templates.txt +0 -0
@@ -0,0 +1,164 @@
1
+ import MISRAReporter from "../MISRAReporter.js";
2
+ import S16_SwitchStatementPass from "../passes/S16_SwitchStatementPass.js";
3
+ import Query from "@specs-feup/lara/api/weaver/Query.js";
4
+ import { FileJp, Joinpoint } from "@specs-feup/clava/api/Joinpoints.js";
5
+ import { expectNumberOfErrors, registerSourceCode, TestFile } from "./utils.js";
6
+
7
+ const passingMisc = `void f ( void )
8
+ {
9
+ int x;
10
+ bool flag;
11
+ switch ( x )
12
+ {
13
+ case 1:
14
+ case 2:
15
+ x = 1;
16
+ break;
17
+ default:
18
+ break;
19
+ }
20
+ switch (x) {
21
+ case 1:
22
+ case 2:
23
+ default:
24
+ break;
25
+ }
26
+ }`;
27
+
28
+ const failingMisc = `void f ( void )
29
+ {
30
+ int x;
31
+ bool flag;
32
+ switch ( x )
33
+ {
34
+ case 1: /* Compliant */
35
+ if ( flag )
36
+ {
37
+ case 2: /* Non-compliant */
38
+ x = 1;
39
+ }
40
+ break;
41
+ default:
42
+ break;
43
+ case 3:
44
+ break;
45
+ }
46
+ switch (x) {
47
+ case 1:
48
+ case 2:
49
+ break;
50
+ }
51
+ }`;
52
+
53
+ const passingFormat = `void f ( void )
54
+ {
55
+ int x, y, z;
56
+ int flag;
57
+ switch (x) {
58
+ case 1:
59
+ z = y+x;
60
+ break;
61
+ case 2:
62
+ z = y-x;
63
+ break;
64
+ default:
65
+ z = 4;
66
+ break;
67
+ }
68
+ switch (flag) {
69
+ case 0:
70
+ x = 2;
71
+ break;
72
+ case 1:
73
+ x = 4;
74
+ break;
75
+ case 2:
76
+ x = 6;
77
+ break;
78
+ }
79
+ switch (z) {
80
+ case 1:
81
+ y = 0;
82
+ break;
83
+ case 6:
84
+ case 42:
85
+ y = 1;
86
+ break;
87
+ case 9139:
88
+ default:
89
+ y = 2;
90
+ break;
91
+ }
92
+ }`;
93
+
94
+ const failingFormat = `void f ( void )
95
+ {
96
+ int x, y, z;
97
+ bool flag;
98
+ switch (x) {
99
+ case 1:
100
+ z = y+x;
101
+ case 2:
102
+ z = y-x;
103
+ break;
104
+ default:
105
+ z = 4;
106
+ }
107
+ switch (flag) {
108
+ case 0:
109
+ x = 2;
110
+ break;
111
+ case 1:
112
+ x = 4;
113
+ break;
114
+ }
115
+ switch (z) {
116
+ case 1:
117
+ case 6:
118
+ case 42:
119
+ y = 1;
120
+ break;
121
+ case 9139:
122
+ default:
123
+ y = 2;
124
+ break;
125
+ }
126
+ }`;
127
+
128
+ const miscFiles: TestFile[] = [
129
+ {name: "badmmisc.cpp", code: failingMisc},
130
+ {name: "goodmisc.cpp", code: passingMisc}
131
+ ];
132
+
133
+ const formatFiles: TestFile[] = [
134
+ {name: "badformat.cpp", code: failingFormat},
135
+ {name: "goodformat.cpp", code: passingFormat}
136
+ ];
137
+
138
+ describe("Switch statements: misc", () => {
139
+ const reporter = new MISRAReporter();
140
+ const pass = new S16_SwitchStatementPass(true, [2, 4, 5]);
141
+ registerSourceCode(miscFiles);
142
+
143
+ it("should pass", () => {
144
+ expectNumberOfErrors(reporter, pass, 0, Query.search(FileJp, {name: "goodmisc.cpp"}).first() as Joinpoint);
145
+ });
146
+
147
+ it("should fail", () => {
148
+ expectNumberOfErrors(reporter, pass, 3, Query.search(FileJp, {name: "badmisc.cpp"}).first() as Joinpoint);
149
+ });
150
+ });
151
+
152
+ describe("Switch statements: format", () => {
153
+ const reporter = new MISRAReporter();
154
+ const pass = new S16_SwitchStatementPass(true, [1, 6, 7]);
155
+ registerSourceCode(formatFiles);
156
+
157
+ it("should pass", () => {
158
+ expectNumberOfErrors(reporter, pass, 0, Query.search(FileJp, {name: "goodformat.cpp"}).first() as Joinpoint);
159
+ });
160
+
161
+ it("should fail", () => {
162
+ expectNumberOfErrors(reporter, pass, 5, Query.search(FileJp, {name: "badformat.cpp"}).first() as Joinpoint);
163
+ });
164
+ });
@@ -0,0 +1,46 @@
1
+ import MISRAReporter from "../MISRAReporter.js";
2
+ import S17_FunctionPass from "../passes/S17_FunctionPass.js";
3
+ import Query from "@specs-feup/lara/api/weaver/Query.js";
4
+ import { FileJp, Joinpoint } from "@specs-feup/clava/api/Joinpoints.js";
5
+ import { expectNumberOfErrors, registerSourceCode, TestFile } from "./utils.js";
6
+
7
+ const passingCode = `int g() {
8
+ return 5;
9
+ }
10
+
11
+ int main(int argc, char *argv[]) {
12
+ (void)g();
13
+
14
+ return 0;
15
+ }`;
16
+
17
+ const failingCode = `#include <stdarg.h>
18
+
19
+ int f() {
20
+ return 5;
21
+ }
22
+
23
+ int test(int argc, char *argv[]) {
24
+ f();
25
+
26
+ return 0;
27
+ }`;
28
+
29
+ const files: TestFile[] = [
30
+ {name: "bad.cpp", code: failingCode},
31
+ {name: "good.cpp", code: passingCode}
32
+ ]
33
+
34
+ describe("Expressions", () => {
35
+ const reporter = new MISRAReporter();
36
+ const pass = new S17_FunctionPass(true, [1, 7]);
37
+ registerSourceCode(files);
38
+
39
+ it("should pass", () => {
40
+ expectNumberOfErrors(reporter, pass, 0, Query.search(FileJp, {name: "good.cpp"}).first() as Joinpoint);
41
+ });
42
+
43
+ it("should fail", () => {
44
+ expectNumberOfErrors(reporter, pass, 2, Query.search(FileJp, {name: "bad.cpp"}).first() as Joinpoint);
45
+ });
46
+ });
@@ -0,0 +1,167 @@
1
+ import MISRAReporter from "../MISRAReporter.js";
2
+ import S18_PointersArraysPass from "../passes/S18_PointersArraysPass.js";
3
+ import Query from "@specs-feup/lara/api/weaver/Query.js";
4
+ import { FileJp, Joinpoint } from "@specs-feup/clava/api/Joinpoints.js";
5
+ import { expectNumberOfErrors, registerSourceCode, TestFile } from "./utils.js";
6
+
7
+ const passingArithmetic = `void fn1 ( void )
8
+ {
9
+ int a[ 10 ];
10
+ int *ptr;
11
+ int index = 0U;
12
+ index = index + 1U; /* Compliant - rule only applies to pointers */
13
+ a[ index ] = 0U; /* Compliant */
14
+ ptr = &a[ 5 ]; /* Compliant */
15
+ ptr = a;
16
+ ptr++; /* Compliant - increment operator not + */
17
+ //*( ptr + 5 ) = 0U; /* Non-compliant */
18
+ ptr[ 5 ] = 0U; /* Compliant */
19
+ }
20
+
21
+ void fn3 ( int *p1, int p2[ ] )
22
+ {
23
+ p1++; /* Compliant */
24
+ //p1 = p1 + 5; /* Non-compliant */
25
+ p1[ 5 ] = 0U; /* Compliant */
26
+ p2++; /* Compliant */
27
+ //p2 = p2 + 3; /* Non-compliant */
28
+ p2[ 3 ] = 0U; /* Compliant */
29
+ }`;
30
+
31
+ const failingArithmetic = `void fn1 ( void )
32
+ {
33
+ int a[ 10 ];
34
+ int *ptr;
35
+ int index = 0U;
36
+ index = index + 1U; /* Compliant - rule only applies to pointers */
37
+ a[ index ] = 0U; /* Compliant */
38
+ ptr = &a[ 5 ]; /* Compliant */
39
+ ptr = a;
40
+ ptr++; /* Compliant - increment operator not + */
41
+ *( ptr + 5 ) = 0U; /* Non-compliant */
42
+ ptr[ 5 ] = 0U; /* Compliant */
43
+ }
44
+
45
+ void fn3 ( int *p1, int p2[ ] )
46
+ {
47
+ p1++; /* Compliant */
48
+ p1 = p1 + 5; /* Non-compliant */
49
+ p1[ 5 ] = 0U; /* Compliant */
50
+ p2++; /* Compliant */
51
+ p2 = p2 + 3; /* Non-compliant */
52
+ p2[ 3 ] = 0U; /* Compliant */
53
+ }`;
54
+
55
+ const passingDepth = ``;
56
+
57
+ const failingDepth = `typedef int * INTPTR;
58
+ void function ( int ** arrPar[ ] ) /* Non-compliant */
59
+ {
60
+ int ** obj2; /* Compliant */
61
+ int *** obj3; /* Non-compliant */
62
+ INTPTR * obj4; /* Compliant */
63
+ INTPTR * const * const obj5 = 0; /* Non-compliant */
64
+ int ** arr[ 10 ]; /* Compliant */
65
+ int ** ( *parr )[ 10 ]; /* Compliant */
66
+ int * ( **pparr )[ 10 ]; /* Compliant */
67
+ }
68
+ struct s
69
+ {
70
+ int * s1; /* Compliant */
71
+ int ** s2; /* Compliant */
72
+ int *** s3; /* Non-compliant */
73
+ };
74
+ struct s * ps1; /* Compliant */
75
+ struct s ** ps2; /* Compliant */
76
+ struct s *** ps3; /* Non-compliant */
77
+ int ** ( *pfunc1 )( void ); /* Compliant */
78
+ int ** ( **pfunc2 )( void ); /* Compliant */
79
+ int ** ( ***pfunc3 )( void ); /* Non-compliant */
80
+ int *** ( **pfunc4 )( void ); /* Non-compliant */`;
81
+
82
+ const failingSizes = `struct s
83
+ {
84
+ unsigned short len;
85
+ unsigned int data[ ]; /* Non-compliant - flexible array member */
86
+ } str;
87
+
88
+ void f ( void )
89
+ {
90
+ int n = 5;
91
+ typedef int Vector[ n ]; /* An array type with 5 elements */
92
+ n = 7;
93
+ Vector a1; /* An array type with 5 elements */
94
+ int a2[ n ]; /* An array type with 7 elements */
95
+ }`;
96
+
97
+ const passingSizes = `struct s
98
+ {
99
+ unsigned short len;
100
+ unsigned int data[ 6 ];
101
+ } str;
102
+
103
+ void f ( void )
104
+ {
105
+ int n = 5;
106
+ typedef int Vector[ 5 ]; /* An array type with 5 elements */
107
+ n = 7;
108
+ Vector a1; /* An array type with 5 elements */
109
+ int a2[ 7 ]; /* An array type with 7 elements */
110
+ }`;
111
+
112
+ const arithmeticFiles: TestFile[] = [
113
+ {name: "badarithmetic.cpp", code: failingArithmetic},
114
+ {name: "goodarithmetic.cpp", code: passingArithmetic}
115
+ ];
116
+
117
+ const depthFiles: TestFile[] = [
118
+ {name: "baddepth.cpp", code: failingDepth},
119
+ {name: "gooddepth.cpp", code: passingDepth}
120
+ ];
121
+
122
+ const sizeFiles: TestFile[] = [
123
+ {name: "goodsizes.cpp", code: passingSizes},
124
+ {name: "badsizes.cpp", code: failingSizes}
125
+ ];
126
+
127
+ describe("Pointers and arrays: arithmetic", () => {
128
+ const reporter = new MISRAReporter();
129
+ const pass = new S18_PointersArraysPass(true, [4]);
130
+ registerSourceCode(arithmeticFiles);
131
+
132
+ it("should pass", () => {
133
+ expectNumberOfErrors(reporter, pass, 0, Query.search(FileJp, {name: "goodarithmetic.cpp"}).first() as Joinpoint);
134
+ });
135
+
136
+ it("should fail", () => {
137
+ expectNumberOfErrors(reporter, pass, 3, Query.search(FileJp, {name: "badarithmetic.cpp"}).first() as Joinpoint);
138
+ });
139
+ });
140
+
141
+ describe("Pointers and arrays: declaration depth", () => {
142
+ const reporter = new MISRAReporter();
143
+ const pass = new S18_PointersArraysPass(true, [5]);
144
+ registerSourceCode(depthFiles);
145
+
146
+ it("should pass", () => {
147
+ expectNumberOfErrors(reporter, pass, 0, Query.search(FileJp, {name: "gooddepth.cpp"}).first() as Joinpoint);
148
+ });
149
+
150
+ it("should fail", () => {
151
+ expectNumberOfErrors(reporter, pass, 7, Query.search(FileJp, {name: "baddepth.cpp"}).first() as Joinpoint);
152
+ });
153
+ });
154
+
155
+ describe("Pointers and arrays: variable size", () => {
156
+ const reporter = new MISRAReporter();
157
+ const pass = new S18_PointersArraysPass(true, [7,8]);
158
+ registerSourceCode(sizeFiles);
159
+
160
+ it("should pass", () => {
161
+ expectNumberOfErrors(reporter, pass, 0, Query.search(FileJp, {name: "goodsizes.cpp"}).first() as Joinpoint);
162
+ });
163
+
164
+ it("should fail", () => {
165
+ expectNumberOfErrors(reporter, pass, 3, Query.search(FileJp, {name: "badsizes.cpp"}).first() as Joinpoint);
166
+ });
167
+ });
@@ -0,0 +1,38 @@
1
+ import MISRAReporter from "../MISRAReporter.js";
2
+ import S19_OverlappingStoragePass from "../passes/S19_OverlappingStoragePass.js";
3
+ import Query from "@specs-feup/lara/api/weaver/Query.js";
4
+ import { FileJp, Joinpoint } from "@specs-feup/clava/api/Joinpoints.js";
5
+ import { expectNumberOfErrors, registerSourceCode, TestFile } from "./utils.js";
6
+
7
+ const passingCode = `struct a {
8
+ int a;
9
+ int b;
10
+ };
11
+
12
+ int main(int argc, char *argv[]) {
13
+ return 0;
14
+ }`;
15
+
16
+ const failingCode = `union a {
17
+ int a;
18
+ int b;
19
+ };`;
20
+
21
+ const files: TestFile[] = [
22
+ {name: "bad.cpp", code: failingCode},
23
+ {name: "good.cpp", code: passingCode}
24
+ ]
25
+
26
+ describe("Expressions", () => {
27
+ const reporter = new MISRAReporter();
28
+ const pass = new S19_OverlappingStoragePass(true, [2]);
29
+ registerSourceCode(files);
30
+
31
+ it("should pass", () => {
32
+ expectNumberOfErrors(reporter, pass, 0, Query.search(FileJp, {name: "good.cpp"}).first() as Joinpoint);
33
+ });
34
+
35
+ it("should fail", () => {
36
+ expectNumberOfErrors(reporter, pass, 1, Query.search(FileJp, {name: "bad.cpp"}).first() as Joinpoint);
37
+ });
38
+ });
@@ -0,0 +1,36 @@
1
+ import MISRAReporter from "../MISRAReporter.js";
2
+ import S3_CommentPass from "../passes/S3_CommentPass.js";
3
+ import Query from "@specs-feup/lara/api/weaver/Query.js";
4
+ import { FileJp, Joinpoint } from "@specs-feup/clava/api/Joinpoints.js";
5
+ import { expectNumberOfErrors, registerSourceCode, TestFile } from "./utils.js";
6
+
7
+ const passingCode = `int main(int argc, char *argv[]) {
8
+ int x, y, z;//good inline comment
9
+ //good comment
10
+ return 0;
11
+ }`;
12
+
13
+ const failingCode = `int test(int argc, char *argv[]) {
14
+ int x, y, z; //bad inl//ine comment
15
+ //bad /*comment
16
+ return 0;
17
+ }`;
18
+
19
+ const files: TestFile[] = [
20
+ {name: "bad.cpp", code: failingCode},
21
+ {name: "good.cpp", code: passingCode}
22
+ ]
23
+
24
+ describe("Expressions", () => {
25
+ const reporter = new MISRAReporter();
26
+ const pass = new S3_CommentPass(true, [3]);
27
+ registerSourceCode(files);
28
+
29
+ it("should pass", () => {
30
+ expectNumberOfErrors(reporter, pass, 0, Query.search(FileJp, {name: "good.cpp"}).first() as Joinpoint);
31
+ });
32
+
33
+ it("should fail", () => {
34
+ expectNumberOfErrors(reporter, pass, 2, Query.search(FileJp, {name: "bad.cpp"}).first() as Joinpoint);
35
+ });
36
+ });
@@ -0,0 +1,36 @@
1
+ import MISRAReporter from "../MISRAReporter.js";
2
+ import S6_TypePass from "../passes/S6_TypePass.js";
3
+ import Query from "@specs-feup/lara/api/weaver/Query.js";
4
+ import { FileJp, Joinpoint } from "@specs-feup/clava/api/Joinpoints.js";
5
+ import { expectNumberOfErrors, registerSourceCode, TestFile } from "./utils.js";
6
+
7
+ const passingCode = `struct good {
8
+ int a:4;
9
+ int:1;
10
+ unsigned int b:8;
11
+ };`;
12
+
13
+ const failingCode = `struct good {
14
+ int a:4;
15
+ int c:1;
16
+ unsigned int b:8;
17
+ };`;
18
+
19
+ const files: TestFile[] = [
20
+ {name: "bad.cpp", code: failingCode},
21
+ {name: "good.cpp", code: passingCode}
22
+ ]
23
+
24
+ describe("Expressions", () => {
25
+ const reporter = new MISRAReporter();
26
+ const pass = new S6_TypePass(true, [2]);
27
+ registerSourceCode(files);
28
+
29
+ it("should pass", () => {
30
+ expectNumberOfErrors(reporter, pass, 0, Query.search(FileJp, {name: "good.cpp"}).first() as Joinpoint);
31
+ });
32
+
33
+ it("should fail", () => {
34
+ expectNumberOfErrors(reporter, pass, 1, Query.search(FileJp, {name: "bad.cpp"}).first() as Joinpoint);
35
+ });
36
+ });
@@ -0,0 +1,48 @@
1
+ import MISRAReporter from "../MISRAReporter.js";
2
+ import S7_LiteralsConstantsPass from "../passes/S7_LiteralsConstantsPass.js";
3
+ import Query from "@specs-feup/lara/api/weaver/Query.js";
4
+ import { FileJp, Joinpoint } from "@specs-feup/clava/api/Joinpoints.js";
5
+ import { expectNumberOfErrors, registerSourceCode, TestFile } from "./utils.js";
6
+
7
+ const passingCode = `void bar(const char* s) {
8
+ return;
9
+ }
10
+
11
+ const char* foo() {
12
+ const char* s = "hello world";
13
+ int a = 12;
14
+ long b = 42L;
15
+ bar("bad call");
16
+ return "bye world";
17
+ }`;
18
+
19
+ const failingCode = `void bar(char* s) {
20
+ return;
21
+ }
22
+
23
+ char* foo() {
24
+ char* s = "hello world";
25
+ int a = 014;
26
+ long b = 42l;
27
+ bar("bad call");
28
+ return "bye world";
29
+ }`;
30
+
31
+ const files: TestFile[] = [
32
+ {name: "bad.cpp", code: failingCode},
33
+ {name: "good.cpp", code: passingCode}
34
+ ]
35
+
36
+ describe("Expressions", () => {
37
+ const reporter = new MISRAReporter();
38
+ const pass = new S7_LiteralsConstantsPass(true, [1, 3, 4]);
39
+ registerSourceCode(files);
40
+
41
+ it("should pass", () => {
42
+ expectNumberOfErrors(reporter, pass, 0, Query.search(FileJp, {name: "good.cpp"}).first() as Joinpoint);
43
+ });
44
+
45
+ it("should fail", () => {
46
+ expectNumberOfErrors(reporter, pass, 5, Query.search(FileJp, {name: "bad.cpp"}).first() as Joinpoint);
47
+ });
48
+ });
@@ -0,0 +1,47 @@
1
+ import AggregatePassResult from "@specs-feup/lara/api/lara/pass/results/AggregatePassResult.js";
2
+ import MISRAPassResult from "../MISRAPassResult.js";
3
+ import MISRAReporter from "../MISRAReporter.js";
4
+ import MISRAPass from "../MISRAPass.js";
5
+ import { Joinpoint } from "@specs-feup/clava/api/Joinpoints.js";
6
+ import Clava from "@specs-feup/clava/api/clava/Clava.js";
7
+ import ClavaJoinPoints from "@specs-feup/clava/api/clava/ClavaJoinPoints.js";
8
+
9
+ function countErrors($passResult: AggregatePassResult): number {
10
+ let count = 0;
11
+ $passResult.results.forEach(res => {
12
+ const misraRes = res as MISRAPassResult;
13
+ count += misraRes.reports.length;
14
+ });
15
+
16
+ return count;
17
+ }
18
+
19
+ export function expectNumberOfErrors($reporter: MISRAReporter, $pass: MISRAPass, $errors: number, $jp: Joinpoint) {
20
+ const result = $reporter.applyPass($pass, $jp);
21
+ if (!result) {
22
+ expect($errors).toBe(0);
23
+ return;
24
+ }
25
+ expect(countErrors(result)).toBe($errors);
26
+ }
27
+
28
+ export interface TestFile {
29
+ name: string,
30
+ code: string
31
+ }
32
+
33
+ export function registerSourceCode(files: TestFile[]): void {
34
+ beforeAll(() => {
35
+ Clava.getProgram().push();
36
+ const program = Clava.getProgram();
37
+ files.forEach(file => {
38
+ const sourceFile = ClavaJoinPoints.fileWithSource(file.name, file.code);
39
+ program.addFile(sourceFile);
40
+ });
41
+ program.rebuild();
42
+ });
43
+
44
+ afterAll(() => {
45
+ Clava.getProgram().pop();
46
+ });
47
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "include": ["**/*.spec.ts", "**/*.test.ts"],
4
+ "exclude": ["node_modules"]
5
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "include": ["src/**/*.ts"],
3
+ "exclude": ["node_modules", "**/*.spec.ts", "**/*.test.ts"],
4
+ "compilerOptions": {
5
+ "outDir": "dist",
6
+ "target": "ES2022",
7
+ "module": "NodeNext",
8
+ "declaration": true,
9
+ "strict": true,
10
+ "allowJs": true,
11
+ "checkJs": true,
12
+ "moduleResolution": "NodeNext",
13
+ "sourceMap": true,
14
+ "declarationMap": true,
15
+ "allowSyntheticDefaultImports": true
16
+ //"esModuleInterop": true
17
+ }
18
+ }
@@ -0,0 +1,6 @@
1
+ import { fileURLToPath } from "url";
2
+
3
+ export default {
4
+ extends: [ fileURLToPath(import.meta.resolve("lara-js/typedoc.base.json")) ],
5
+ entryPoints: ["src/"],
6
+ }
File without changes