yukigo 0.1.0 → 0.2.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 (144) hide show
  1. package/.mocharc.json +3 -3
  2. package/CHANGELOG.md +26 -0
  3. package/README.md +193 -199
  4. package/dist/analyzer/GraphBuilder.d.ts +29 -0
  5. package/dist/analyzer/GraphBuilder.js +99 -0
  6. package/dist/analyzer/index.d.ts +11 -23
  7. package/dist/analyzer/index.js +100 -58
  8. package/dist/analyzer/inspections/functional/functional.d.ts +44 -0
  9. package/dist/analyzer/inspections/functional/functional.js +149 -0
  10. package/dist/analyzer/inspections/functional/smells.d.ts +16 -0
  11. package/dist/analyzer/inspections/functional/smells.js +98 -0
  12. package/dist/analyzer/inspections/{generic.d.ts → generic/generic.d.ts} +70 -43
  13. package/dist/analyzer/inspections/generic/generic.js +604 -0
  14. package/dist/analyzer/inspections/generic/smells.d.ts +61 -0
  15. package/dist/analyzer/inspections/generic/smells.js +349 -0
  16. package/dist/analyzer/inspections/imperative/imperative.d.ts +35 -0
  17. package/dist/analyzer/inspections/imperative/imperative.js +109 -0
  18. package/dist/analyzer/inspections/imperative/smells.d.ts +16 -0
  19. package/dist/analyzer/inspections/imperative/smells.js +58 -0
  20. package/dist/analyzer/inspections/logic/logic.d.ts +32 -0
  21. package/dist/analyzer/inspections/logic/logic.js +96 -0
  22. package/dist/analyzer/inspections/logic/smells.d.ts +15 -0
  23. package/dist/analyzer/inspections/logic/smells.js +60 -0
  24. package/dist/analyzer/inspections/object/object.d.ts +88 -0
  25. package/dist/analyzer/inspections/object/object.js +319 -0
  26. package/dist/analyzer/inspections/object/smells.d.ts +30 -0
  27. package/dist/analyzer/inspections/object/smells.js +135 -0
  28. package/dist/analyzer/utils.d.ts +26 -4
  29. package/dist/analyzer/utils.js +71 -13
  30. package/dist/index.d.ts +1 -0
  31. package/dist/index.js +1 -0
  32. package/dist/interpreter/components/EnvBuilder.d.ts +9 -5
  33. package/dist/interpreter/components/EnvBuilder.js +100 -30
  34. package/dist/interpreter/components/Operations.d.ts +4 -4
  35. package/dist/interpreter/components/Operations.js +17 -2
  36. package/dist/interpreter/components/PatternMatcher.d.ts +47 -17
  37. package/dist/interpreter/components/PatternMatcher.js +264 -119
  38. package/dist/interpreter/components/RuntimeContext.d.ts +35 -0
  39. package/dist/interpreter/components/RuntimeContext.js +93 -0
  40. package/dist/interpreter/components/TestRunner.d.ts +18 -0
  41. package/dist/interpreter/components/TestRunner.js +103 -0
  42. package/dist/interpreter/components/Visitor.d.ts +63 -57
  43. package/dist/interpreter/components/Visitor.js +508 -173
  44. package/dist/interpreter/components/logic/LogicEngine.d.ts +29 -0
  45. package/dist/interpreter/components/logic/LogicEngine.js +259 -0
  46. package/dist/interpreter/components/logic/LogicResolver.d.ts +53 -0
  47. package/dist/interpreter/components/logic/LogicResolver.js +471 -0
  48. package/dist/interpreter/components/logic/LogicTranslator.d.ts +14 -0
  49. package/dist/interpreter/components/logic/LogicTranslator.js +99 -0
  50. package/dist/interpreter/components/runtimes/FunctionRuntime.d.ts +12 -0
  51. package/dist/interpreter/components/runtimes/FunctionRuntime.js +147 -0
  52. package/dist/interpreter/components/runtimes/LazyRuntime.d.ts +19 -0
  53. package/dist/interpreter/components/runtimes/LazyRuntime.js +269 -0
  54. package/dist/interpreter/components/runtimes/ObjectRuntime.d.ts +35 -0
  55. package/dist/interpreter/components/runtimes/ObjectRuntime.js +126 -0
  56. package/dist/interpreter/entities.d.ts +105 -0
  57. package/dist/interpreter/entities.js +96 -0
  58. package/dist/interpreter/errors.d.ts +1 -1
  59. package/dist/interpreter/index.d.ts +4 -12
  60. package/dist/interpreter/index.js +10 -13
  61. package/dist/interpreter/trampoline.d.ts +17 -0
  62. package/dist/interpreter/trampoline.js +38 -0
  63. package/dist/interpreter/utils.d.ts +4 -7
  64. package/dist/interpreter/utils.js +25 -17
  65. package/dist/tester/index.d.ts +25 -0
  66. package/dist/tester/index.js +108 -0
  67. package/dist/utils/helpers.d.ts +0 -4
  68. package/dist/utils/helpers.js +20 -24
  69. package/package.json +2 -2
  70. package/src/analyzer/GraphBuilder.ts +142 -0
  71. package/src/analyzer/index.ts +185 -132
  72. package/src/analyzer/inspections/functional/functional.ts +121 -0
  73. package/src/analyzer/inspections/functional/smells.ts +102 -0
  74. package/src/analyzer/inspections/{generic.ts → generic/generic.ts} +581 -499
  75. package/src/analyzer/inspections/generic/smells.ts +365 -0
  76. package/src/analyzer/inspections/imperative/imperative.ts +101 -0
  77. package/src/analyzer/inspections/imperative/smells.ts +54 -0
  78. package/src/analyzer/inspections/logic/logic.ts +90 -0
  79. package/src/analyzer/inspections/logic/smells.ts +54 -0
  80. package/src/analyzer/inspections/{object.ts → object/object.ts} +264 -282
  81. package/src/analyzer/inspections/object/smells.ts +144 -0
  82. package/src/analyzer/utils.ts +109 -26
  83. package/src/index.ts +3 -2
  84. package/src/interpreter/components/EnvBuilder.ts +202 -97
  85. package/src/interpreter/components/Operations.ts +99 -81
  86. package/src/interpreter/components/PatternMatcher.ts +475 -254
  87. package/src/interpreter/components/RuntimeContext.ts +119 -0
  88. package/src/interpreter/components/TestRunner.ts +151 -0
  89. package/src/interpreter/components/Visitor.ts +1065 -493
  90. package/src/interpreter/components/logic/LogicEngine.ts +519 -0
  91. package/src/interpreter/components/logic/LogicResolver.ts +858 -0
  92. package/src/interpreter/components/logic/LogicTranslator.ts +149 -0
  93. package/src/interpreter/components/runtimes/FunctionRuntime.ts +227 -0
  94. package/src/interpreter/components/runtimes/LazyRuntime.ts +334 -0
  95. package/src/interpreter/components/runtimes/ObjectRuntime.ts +224 -0
  96. package/src/interpreter/errors.ts +47 -47
  97. package/src/interpreter/index.ts +52 -59
  98. package/src/interpreter/trampoline.ts +71 -0
  99. package/src/interpreter/utils.ts +84 -79
  100. package/src/tester/index.ts +128 -0
  101. package/src/utils/helpers.ts +67 -73
  102. package/tests/analyzer/functional.spec.ts +207 -221
  103. package/tests/analyzer/generic.spec.ts +178 -100
  104. package/tests/analyzer/helpers.spec.ts +83 -83
  105. package/tests/analyzer/logic.spec.ts +237 -292
  106. package/tests/analyzer/oop.spec.ts +323 -338
  107. package/tests/analyzer/transitive.spec.ts +166 -0
  108. package/tests/interpreter/EnvBuilder.spec.ts +183 -178
  109. package/tests/interpreter/FunctionRuntime.spec.ts +223 -234
  110. package/tests/interpreter/LazyRuntime.spec.ts +225 -190
  111. package/tests/interpreter/LogicEngine.spec.ts +327 -194
  112. package/tests/interpreter/LogicSubstitution.spec.ts +80 -0
  113. package/tests/interpreter/ObjectRuntime.spec.ts +606 -0
  114. package/tests/interpreter/Operations.spec.ts +220 -220
  115. package/tests/interpreter/PatternSystem.spec.ts +213 -189
  116. package/tests/interpreter/Tests.spec.ts +122 -0
  117. package/tests/interpreter/interpreter.spec.ts +991 -937
  118. package/tests/tester/Tester.spec.ts +153 -0
  119. package/tsconfig.build.json +15 -7
  120. package/tsconfig.json +25 -17
  121. package/dist/analyzer/inspections/functional.d.ts +0 -46
  122. package/dist/analyzer/inspections/functional.js +0 -123
  123. package/dist/analyzer/inspections/generic.js +0 -427
  124. package/dist/analyzer/inspections/imperative.d.ts +0 -37
  125. package/dist/analyzer/inspections/imperative.js +0 -105
  126. package/dist/analyzer/inspections/logic.d.ts +0 -49
  127. package/dist/analyzer/inspections/logic.js +0 -140
  128. package/dist/analyzer/inspections/object.d.ts +0 -83
  129. package/dist/analyzer/inspections/object.js +0 -235
  130. package/dist/interpreter/components/FunctionRuntime.d.ts +0 -8
  131. package/dist/interpreter/components/FunctionRuntime.js +0 -52
  132. package/dist/interpreter/components/LazyRuntime.d.ts +0 -7
  133. package/dist/interpreter/components/LazyRuntime.js +0 -75
  134. package/dist/interpreter/components/LogicEngine.d.ts +0 -21
  135. package/dist/interpreter/components/LogicEngine.js +0 -152
  136. package/dist/interpreter/components/LogicResolver.d.ts +0 -11
  137. package/dist/interpreter/components/LogicResolver.js +0 -87
  138. package/src/analyzer/inspections/functional.ts +0 -159
  139. package/src/analyzer/inspections/imperative.ts +0 -129
  140. package/src/analyzer/inspections/logic.ts +0 -166
  141. package/src/interpreter/components/FunctionRuntime.ts +0 -79
  142. package/src/interpreter/components/LazyRuntime.ts +0 -97
  143. package/src/interpreter/components/LogicEngine.ts +0 -227
  144. package/src/interpreter/components/LogicResolver.ts +0 -130
@@ -0,0 +1,153 @@
1
+ import { expect } from "chai";
2
+ import {
3
+ Assert,
4
+ BooleanPrimitive,
5
+ Equality,
6
+ NumberPrimitive,
7
+ Sequence,
8
+ Test,
9
+ TestGroup,
10
+ StringPrimitive,
11
+ Variable,
12
+ SymbolPrimitive,
13
+ ArithmeticBinaryOperation,
14
+ Lambda,
15
+ Call,
16
+ Application,
17
+ VariablePattern,
18
+ } from "yukigo-ast";
19
+ import { Tester } from "../../src/tester/index.js";
20
+
21
+ describe("Tester class", () => {
22
+ it("should run a simple passing test", () => {
23
+ const passingTest = new Test(
24
+ new StringPrimitive("Success"),
25
+ new Sequence([
26
+ new Assert(
27
+ new BooleanPrimitive(false),
28
+ new Equality(new NumberPrimitive(1), new NumberPrimitive(1)),
29
+ ),
30
+ ]),
31
+ );
32
+
33
+ const tester = new Tester([passingTest]);
34
+ const results = tester.test([passingTest]);
35
+
36
+ expect(results).to.have.lengthOf(1);
37
+ expect(results[0].name).to.equal("Success");
38
+ expect(results[0].status).to.equal("passed");
39
+ });
40
+
41
+ it("should report a failing test with a message", () => {
42
+ const failingTest = new Test(
43
+ new StringPrimitive("Failure"),
44
+ new Sequence([
45
+ new Assert(
46
+ new BooleanPrimitive(false),
47
+ new Equality(new NumberPrimitive(1), new NumberPrimitive(2)),
48
+ ),
49
+ ]),
50
+ );
51
+
52
+ const tester = new Tester([failingTest]);
53
+ const results = tester.test([failingTest]);
54
+
55
+ expect(results).to.have.lengthOf(1);
56
+ expect(results[0].status).to.equal("failed");
57
+ expect(results[0].message).to.contain("Expected 1, but got 2");
58
+ });
59
+
60
+ it("should run tests inside a TestGroup independently", () => {
61
+ const passingTest = new Test(
62
+ new StringPrimitive("Pass"),
63
+ new Sequence([
64
+ new Assert(
65
+ new BooleanPrimitive(false),
66
+ new Equality(new NumberPrimitive(10), new NumberPrimitive(10)),
67
+ ),
68
+ ]),
69
+ );
70
+
71
+ const failingTest = new Test(
72
+ new StringPrimitive("Fail"),
73
+ new Sequence([
74
+ new Assert(
75
+ new BooleanPrimitive(false),
76
+ new Equality(new NumberPrimitive(1), new NumberPrimitive(0)),
77
+ ),
78
+ ]),
79
+ );
80
+
81
+ const group = new TestGroup(
82
+ new StringPrimitive("My Group"),
83
+ new Sequence([passingTest, failingTest]),
84
+ );
85
+
86
+ const tester = new Tester([group]);
87
+ const results = tester.test([group]);
88
+
89
+ expect(results).to.have.lengthOf(1);
90
+ const groupReport = results[0];
91
+ expect(groupReport.name).to.equal("My Group");
92
+ expect(groupReport.status).to.equal("failed");
93
+ expect(groupReport.children).to.have.lengthOf(2);
94
+ expect(groupReport.children![0].status).to.equal("passed");
95
+ expect(groupReport.children![1].status).to.equal("failed");
96
+ });
97
+
98
+ it("should handle setup code inside a TestGroup", () => {
99
+ // var x = 5
100
+ const setup = new Variable(
101
+ new SymbolPrimitive("x"),
102
+ new NumberPrimitive(5),
103
+ );
104
+
105
+ // test "Check X" { assert x == 5 }
106
+ const checkX = new Test(
107
+ new StringPrimitive("Check X"),
108
+ new Sequence([
109
+ new Assert(
110
+ new BooleanPrimitive(false),
111
+ new Equality(new SymbolPrimitive("x"), new NumberPrimitive(5)),
112
+ ),
113
+ ]),
114
+ );
115
+
116
+ const group = new TestGroup(
117
+ new StringPrimitive("Setup Group"),
118
+ new Sequence([setup, checkX]),
119
+ );
120
+
121
+ const tester = new Tester([group]);
122
+ const results = tester.test([group]);
123
+
124
+ expect(results[0].children).to.have.lengthOf(1);
125
+ expect(results[0].children![0].status).to.equal("passed");
126
+ });
127
+
128
+ it("should report errors that are not FailedAssert", () => {
129
+ // test "Error" { 1 + "a" }
130
+ const errorTest = new Test(
131
+ new StringPrimitive("Error"),
132
+ new Sequence([
133
+ new Application(
134
+ new Lambda(
135
+ [new VariablePattern(new SymbolPrimitive("b"))],
136
+ new ArithmeticBinaryOperation(
137
+ "Plus",
138
+ new SymbolPrimitive("b"),
139
+ new StringPrimitive("a"),
140
+ ),
141
+ ),
142
+ new NumberPrimitive(1),
143
+ ),
144
+ ]),
145
+ );
146
+
147
+ const tester = new Tester([errorTest]);
148
+ const results = tester.test([errorTest]);
149
+
150
+ expect(results[0].status).to.equal("error");
151
+ expect(results[0].message).to.contain("Type mismatch");
152
+ });
153
+ });
@@ -1,7 +1,15 @@
1
- {
2
- "extends": "./tsconfig.json",
3
- "compilerOptions": {
4
- "noEmit": false
5
- },
6
- "exclude": ["dist/**/*", "tests/**/*"]
7
- }
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "noEmit": false
5
+ },
6
+ "exclude": [
7
+ "dist/**/*",
8
+ "tests/**/*"
9
+ ],
10
+ "references": [
11
+ {
12
+ "path": "../yukigo-ast"
13
+ }
14
+ ],
15
+ }
package/tsconfig.json CHANGED
@@ -1,17 +1,25 @@
1
- {
2
- "compilerOptions": {
3
- "target": "es2024",
4
- "module": "nodenext",
5
- "moduleResolution": "nodenext",
6
- "lib": ["es2024", "dom"],
7
- "outDir": "./dist",
8
- "declaration": true,
9
- "esModuleInterop": true,
10
- "allowSyntheticDefaultImports": true,
11
- "forceConsistentCasingInFileNames": true,
12
- "skipLibCheck": true,
13
- "noEmit": true
14
- },
15
- "include": ["**/*"],
16
- "exclude": ["dist/**/*"]
17
- }
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es2024",
4
+ "experimentalDecorators": true,
5
+ "module": "nodenext",
6
+ "moduleResolution": "nodenext",
7
+ "lib": ["es2024", "dom"],
8
+ "outDir": "./dist",
9
+ "declaration": true,
10
+ "esModuleInterop": true,
11
+ "allowSyntheticDefaultImports": true,
12
+ "forceConsistentCasingInFileNames": true,
13
+ "skipLibCheck": true,
14
+ "noEmit": true
15
+ },
16
+ "include": ["src"],
17
+ "exclude": [
18
+ "dist/**/*"
19
+ ],
20
+ "references": [
21
+ {
22
+ "path": "../yukigo-ast"
23
+ }
24
+ ]
25
+ }
@@ -1,46 +0,0 @@
1
- import { ApplicationPattern, AsPattern, CompositionExpression, ConsPattern, ConstructorPattern, Fact, Function, FunctorPattern, GuardedBody, Lambda, ListComprehension, ListPattern, LiteralPattern, Rule, TraverseVisitor, TuplePattern, UnionPattern, WildcardPattern, Yield } from "@yukigo/ast";
2
- import { InspectionMap } from "../utils.js";
3
- export declare class FunctionVisitor extends TraverseVisitor {
4
- private readonly targetBinding;
5
- protected isInsideTargetScope: boolean;
6
- constructor(binding: string);
7
- visitFunction(node: Function): void;
8
- }
9
- export declare class UsesComposition extends FunctionVisitor {
10
- visitCompositionExpression(node: CompositionExpression): void;
11
- }
12
- export declare class UsesAnonymousVariable extends TraverseVisitor {
13
- private readonly targetBinding;
14
- protected isInsideTargetScope: boolean;
15
- constructor(binding: string);
16
- visitWildcardPattern(node: WildcardPattern): void;
17
- visitFunction(node: Function): void;
18
- visitFact(node: Fact): void;
19
- visitRule(node: Rule): void;
20
- private enterScope;
21
- }
22
- export declare class UsesComprehension extends FunctionVisitor {
23
- visitListComprehension(node: ListComprehension): void;
24
- }
25
- export declare class UsesGuards extends FunctionVisitor {
26
- visitGuardedBody(node: GuardedBody): void;
27
- }
28
- export declare class UsesLambda extends FunctionVisitor {
29
- visitLambda(node: Lambda): void;
30
- }
31
- export declare class UsesYield extends FunctionVisitor {
32
- visitYield(node: Yield): void;
33
- }
34
- export declare class UsesPatternMatching extends FunctionVisitor {
35
- visitConsPattern(node: ConsPattern): void;
36
- visitAsPattern(node: AsPattern): void;
37
- visitListPattern(node: ListPattern): void;
38
- visitTuplePattern(node: TuplePattern): void;
39
- visitLiteralPattern(node: LiteralPattern): void;
40
- visitApplicationPattern(node: ApplicationPattern): void;
41
- visitConstructorPattern(node: ConstructorPattern): void;
42
- visitUnionPattern(node: UnionPattern): void;
43
- visitFunctorPattern(node: FunctorPattern): void;
44
- visitWildcardPattern(node: WildcardPattern): void;
45
- }
46
- export declare const functionalInspections: InspectionMap;
@@ -1,123 +0,0 @@
1
- import { StopTraversalException, TraverseVisitor, } from "@yukigo/ast";
2
- import { executeVisitor } from "../utils.js";
3
- export class FunctionVisitor extends TraverseVisitor {
4
- targetBinding;
5
- isInsideTargetScope = false; // this flag helps to check nested functions inside the targetBinding scope
6
- constructor(binding) {
7
- super();
8
- this.targetBinding = binding;
9
- }
10
- visitFunction(node) {
11
- const currentFunctionName = node.identifier.value;
12
- // if not inside scope then is top-level
13
- if (!this.isInsideTargetScope) {
14
- if (!this.targetBinding || currentFunctionName === this.targetBinding) {
15
- this.isInsideTargetScope = true;
16
- this.traverseCollection(node.equations);
17
- this.isInsideTargetScope = false;
18
- return;
19
- }
20
- return;
21
- }
22
- // if inside the scope of targetBinding then traverse
23
- this.traverseCollection(node.equations);
24
- }
25
- }
26
- export class UsesComposition extends FunctionVisitor {
27
- visitCompositionExpression(node) {
28
- throw new StopTraversalException();
29
- }
30
- }
31
- export class UsesAnonymousVariable extends TraverseVisitor {
32
- targetBinding;
33
- isInsideTargetScope = false;
34
- constructor(binding) {
35
- super();
36
- this.targetBinding = binding;
37
- }
38
- visitWildcardPattern(node) {
39
- throw new StopTraversalException();
40
- }
41
- visitFunction(node) {
42
- this.enterScope(node, node.equations);
43
- }
44
- visitFact(node) {
45
- this.enterScope(node, node.patterns);
46
- }
47
- visitRule(node) {
48
- this.enterScope(node, node.patterns);
49
- }
50
- enterScope(node, children) {
51
- const nodeName = node.identifier.value;
52
- if (!this.isInsideTargetScope) {
53
- if (!this.targetBinding || nodeName === this.targetBinding) {
54
- this.isInsideTargetScope = true;
55
- this.traverseCollection(children);
56
- this.isInsideTargetScope = false;
57
- }
58
- return;
59
- }
60
- this.traverseCollection(children);
61
- }
62
- }
63
- export class UsesComprehension extends FunctionVisitor {
64
- visitListComprehension(node) {
65
- throw new StopTraversalException();
66
- }
67
- }
68
- export class UsesGuards extends FunctionVisitor {
69
- visitGuardedBody(node) {
70
- throw new StopTraversalException();
71
- }
72
- }
73
- export class UsesLambda extends FunctionVisitor {
74
- visitLambda(node) {
75
- throw new StopTraversalException();
76
- }
77
- }
78
- export class UsesYield extends FunctionVisitor {
79
- visitYield(node) {
80
- throw new StopTraversalException();
81
- }
82
- }
83
- export class UsesPatternMatching extends FunctionVisitor {
84
- visitConsPattern(node) {
85
- throw new StopTraversalException();
86
- }
87
- visitAsPattern(node) {
88
- throw new StopTraversalException();
89
- }
90
- visitListPattern(node) {
91
- throw new StopTraversalException();
92
- }
93
- visitTuplePattern(node) {
94
- throw new StopTraversalException();
95
- }
96
- visitLiteralPattern(node) {
97
- throw new StopTraversalException();
98
- }
99
- visitApplicationPattern(node) {
100
- throw new StopTraversalException();
101
- }
102
- visitConstructorPattern(node) {
103
- throw new StopTraversalException();
104
- }
105
- visitUnionPattern(node) {
106
- throw new StopTraversalException();
107
- }
108
- visitFunctorPattern(node) {
109
- throw new StopTraversalException();
110
- }
111
- visitWildcardPattern(node) {
112
- throw new StopTraversalException();
113
- }
114
- }
115
- export const functionalInspections = {
116
- UsesComposition: (node, args, binding) => executeVisitor(node, new UsesComposition(binding)),
117
- UsesAnonymousVariable: (node, args, binding) => executeVisitor(node, new UsesAnonymousVariable(binding)),
118
- UsesComprehension: (node, args, binding) => executeVisitor(node, new UsesComprehension(binding)),
119
- UsesGuards: (node, args, binding) => executeVisitor(node, new UsesGuards(binding)),
120
- UsesLambda: (node, args, binding) => executeVisitor(node, new UsesLambda(binding)),
121
- UsesYield: (node, args, binding) => executeVisitor(node, new UsesYield(binding)),
122
- UsesPatternMatching: (node, args, binding) => executeVisitor(node, new UsesPatternMatching(binding)),
123
- };