@vibe-lang/runtime 0.2.5

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 (250) hide show
  1. package/package.json +46 -0
  2. package/src/ast/index.ts +375 -0
  3. package/src/ast.ts +2 -0
  4. package/src/debug/advanced-features.ts +482 -0
  5. package/src/debug/bun-inspector.ts +424 -0
  6. package/src/debug/handoff-manager.ts +283 -0
  7. package/src/debug/index.ts +150 -0
  8. package/src/debug/runner.ts +365 -0
  9. package/src/debug/server.ts +565 -0
  10. package/src/debug/stack-merger.ts +267 -0
  11. package/src/debug/state.ts +581 -0
  12. package/src/debug/test/advanced-features.test.ts +300 -0
  13. package/src/debug/test/e2e.test.ts +218 -0
  14. package/src/debug/test/handoff-manager.test.ts +256 -0
  15. package/src/debug/test/runner.test.ts +256 -0
  16. package/src/debug/test/stack-merger.test.ts +163 -0
  17. package/src/debug/test/state.test.ts +400 -0
  18. package/src/debug/test/ts-debug-integration.test.ts +374 -0
  19. package/src/debug/test/ts-import-tracker.test.ts +125 -0
  20. package/src/debug/test/ts-source-map.test.ts +169 -0
  21. package/src/debug/ts-import-tracker.ts +151 -0
  22. package/src/debug/ts-source-map.ts +171 -0
  23. package/src/errors/index.ts +124 -0
  24. package/src/index.ts +358 -0
  25. package/src/lexer/index.ts +348 -0
  26. package/src/lexer.ts +2 -0
  27. package/src/parser/index.ts +792 -0
  28. package/src/parser/parse.ts +45 -0
  29. package/src/parser/test/async.test.ts +248 -0
  30. package/src/parser/test/destructuring.test.ts +167 -0
  31. package/src/parser/test/do-expression.test.ts +486 -0
  32. package/src/parser/test/errors/do-expression.test.ts +95 -0
  33. package/src/parser/test/errors/error-locations.test.ts +230 -0
  34. package/src/parser/test/errors/invalid-expressions.test.ts +144 -0
  35. package/src/parser/test/errors/missing-tokens.test.ts +126 -0
  36. package/src/parser/test/errors/model-declaration.test.ts +185 -0
  37. package/src/parser/test/errors/nested-blocks.test.ts +226 -0
  38. package/src/parser/test/errors/unclosed-delimiters.test.ts +122 -0
  39. package/src/parser/test/errors/unexpected-tokens.test.ts +120 -0
  40. package/src/parser/test/import-export.test.ts +143 -0
  41. package/src/parser/test/literals.test.ts +404 -0
  42. package/src/parser/test/model-declaration.test.ts +161 -0
  43. package/src/parser/test/nested-blocks.test.ts +402 -0
  44. package/src/parser/test/parser.test.ts +743 -0
  45. package/src/parser/test/private.test.ts +136 -0
  46. package/src/parser/test/template-literal.test.ts +127 -0
  47. package/src/parser/test/tool-declaration.test.ts +302 -0
  48. package/src/parser/test/ts-block.test.ts +252 -0
  49. package/src/parser/test/type-annotations.test.ts +254 -0
  50. package/src/parser/visitor/helpers.ts +330 -0
  51. package/src/parser/visitor.ts +794 -0
  52. package/src/parser.ts +2 -0
  53. package/src/runtime/ai/cache-chunking.test.ts +69 -0
  54. package/src/runtime/ai/cache-chunking.ts +73 -0
  55. package/src/runtime/ai/client.ts +109 -0
  56. package/src/runtime/ai/context.ts +168 -0
  57. package/src/runtime/ai/formatters.ts +316 -0
  58. package/src/runtime/ai/index.ts +38 -0
  59. package/src/runtime/ai/language-ref.ts +38 -0
  60. package/src/runtime/ai/providers/anthropic.ts +253 -0
  61. package/src/runtime/ai/providers/google.ts +201 -0
  62. package/src/runtime/ai/providers/openai.ts +156 -0
  63. package/src/runtime/ai/retry.ts +100 -0
  64. package/src/runtime/ai/return-tools.ts +301 -0
  65. package/src/runtime/ai/test/client.test.ts +83 -0
  66. package/src/runtime/ai/test/formatters.test.ts +485 -0
  67. package/src/runtime/ai/test/retry.test.ts +137 -0
  68. package/src/runtime/ai/test/return-tools.test.ts +450 -0
  69. package/src/runtime/ai/test/tool-loop.test.ts +319 -0
  70. package/src/runtime/ai/test/tool-schema.test.ts +241 -0
  71. package/src/runtime/ai/tool-loop.ts +203 -0
  72. package/src/runtime/ai/tool-schema.ts +151 -0
  73. package/src/runtime/ai/types.ts +113 -0
  74. package/src/runtime/ai-logger.ts +255 -0
  75. package/src/runtime/ai-provider.ts +347 -0
  76. package/src/runtime/async/dependencies.ts +276 -0
  77. package/src/runtime/async/executor.ts +293 -0
  78. package/src/runtime/async/index.ts +43 -0
  79. package/src/runtime/async/scheduling.ts +163 -0
  80. package/src/runtime/async/test/dependencies.test.ts +284 -0
  81. package/src/runtime/async/test/executor.test.ts +388 -0
  82. package/src/runtime/context.ts +357 -0
  83. package/src/runtime/exec/ai.ts +139 -0
  84. package/src/runtime/exec/expressions.ts +475 -0
  85. package/src/runtime/exec/frames.ts +26 -0
  86. package/src/runtime/exec/functions.ts +305 -0
  87. package/src/runtime/exec/interpolation.ts +312 -0
  88. package/src/runtime/exec/statements.ts +604 -0
  89. package/src/runtime/exec/tools.ts +129 -0
  90. package/src/runtime/exec/typescript.ts +215 -0
  91. package/src/runtime/exec/variables.ts +279 -0
  92. package/src/runtime/index.ts +975 -0
  93. package/src/runtime/modules.ts +452 -0
  94. package/src/runtime/serialize.ts +103 -0
  95. package/src/runtime/state.ts +489 -0
  96. package/src/runtime/stdlib/core.ts +45 -0
  97. package/src/runtime/stdlib/directory.test.ts +156 -0
  98. package/src/runtime/stdlib/edit.test.ts +154 -0
  99. package/src/runtime/stdlib/fastEdit.test.ts +201 -0
  100. package/src/runtime/stdlib/glob.test.ts +106 -0
  101. package/src/runtime/stdlib/grep.test.ts +144 -0
  102. package/src/runtime/stdlib/index.ts +16 -0
  103. package/src/runtime/stdlib/readFile.test.ts +123 -0
  104. package/src/runtime/stdlib/tools/index.ts +707 -0
  105. package/src/runtime/stdlib/writeFile.test.ts +157 -0
  106. package/src/runtime/step.ts +969 -0
  107. package/src/runtime/test/ai-context.test.ts +1086 -0
  108. package/src/runtime/test/ai-result-object.test.ts +419 -0
  109. package/src/runtime/test/ai-tool-flow.test.ts +859 -0
  110. package/src/runtime/test/async-execution-order.test.ts +618 -0
  111. package/src/runtime/test/async-execution.test.ts +344 -0
  112. package/src/runtime/test/async-nested.test.ts +660 -0
  113. package/src/runtime/test/async-parallel-timing.test.ts +546 -0
  114. package/src/runtime/test/basic1.test.ts +154 -0
  115. package/src/runtime/test/binary-operators.test.ts +431 -0
  116. package/src/runtime/test/break-statement.test.ts +257 -0
  117. package/src/runtime/test/context-modes.test.ts +650 -0
  118. package/src/runtime/test/context.test.ts +466 -0
  119. package/src/runtime/test/core-functions.test.ts +228 -0
  120. package/src/runtime/test/e2e.test.ts +88 -0
  121. package/src/runtime/test/error-locations/error-locations.test.ts +80 -0
  122. package/src/runtime/test/error-locations/main-error.vibe +4 -0
  123. package/src/runtime/test/error-locations/main-import-error.vibe +3 -0
  124. package/src/runtime/test/error-locations/utils/helper.vibe +5 -0
  125. package/src/runtime/test/for-in.test.ts +312 -0
  126. package/src/runtime/test/helpers.ts +69 -0
  127. package/src/runtime/test/imports.test.ts +334 -0
  128. package/src/runtime/test/json-expressions.test.ts +232 -0
  129. package/src/runtime/test/literals.test.ts +372 -0
  130. package/src/runtime/test/logical-indexing.test.ts +478 -0
  131. package/src/runtime/test/member-methods.test.ts +324 -0
  132. package/src/runtime/test/model-config.test.ts +338 -0
  133. package/src/runtime/test/null-handling.test.ts +342 -0
  134. package/src/runtime/test/private-visibility.test.ts +332 -0
  135. package/src/runtime/test/runtime-state.test.ts +514 -0
  136. package/src/runtime/test/scoping.test.ts +370 -0
  137. package/src/runtime/test/string-interpolation.test.ts +354 -0
  138. package/src/runtime/test/template-literal.test.ts +181 -0
  139. package/src/runtime/test/tool-execution.test.ts +467 -0
  140. package/src/runtime/test/tool-schema-generation.test.ts +477 -0
  141. package/src/runtime/test/tostring.test.ts +210 -0
  142. package/src/runtime/test/ts-block.test.ts +594 -0
  143. package/src/runtime/test/ts-error-location.test.ts +231 -0
  144. package/src/runtime/test/types.test.ts +732 -0
  145. package/src/runtime/test/verbose-logger.test.ts +710 -0
  146. package/src/runtime/test/vibe-expression.test.ts +54 -0
  147. package/src/runtime/test/vibe-value-errors.test.ts +541 -0
  148. package/src/runtime/test/while.test.ts +232 -0
  149. package/src/runtime/tools/builtin.ts +30 -0
  150. package/src/runtime/tools/directory-tools.ts +70 -0
  151. package/src/runtime/tools/file-tools.ts +228 -0
  152. package/src/runtime/tools/index.ts +5 -0
  153. package/src/runtime/tools/registry.ts +48 -0
  154. package/src/runtime/tools/search-tools.ts +134 -0
  155. package/src/runtime/tools/security.ts +36 -0
  156. package/src/runtime/tools/system-tools.ts +312 -0
  157. package/src/runtime/tools/test/fixtures/base-types.ts +40 -0
  158. package/src/runtime/tools/test/fixtures/test-types.ts +132 -0
  159. package/src/runtime/tools/test/registry.test.ts +713 -0
  160. package/src/runtime/tools/test/security.test.ts +86 -0
  161. package/src/runtime/tools/test/system-tools.test.ts +679 -0
  162. package/src/runtime/tools/test/ts-schema.test.ts +357 -0
  163. package/src/runtime/tools/ts-schema.ts +341 -0
  164. package/src/runtime/tools/types.ts +89 -0
  165. package/src/runtime/tools/utility-tools.ts +198 -0
  166. package/src/runtime/ts-eval.ts +126 -0
  167. package/src/runtime/types.ts +797 -0
  168. package/src/runtime/validation.ts +160 -0
  169. package/src/runtime/verbose-logger.ts +459 -0
  170. package/src/runtime.ts +2 -0
  171. package/src/semantic/analyzer-context.ts +62 -0
  172. package/src/semantic/analyzer-validators.ts +575 -0
  173. package/src/semantic/analyzer-visitors.ts +534 -0
  174. package/src/semantic/analyzer.ts +83 -0
  175. package/src/semantic/index.ts +11 -0
  176. package/src/semantic/symbol-table.ts +58 -0
  177. package/src/semantic/test/async-validation.test.ts +301 -0
  178. package/src/semantic/test/compress-validation.test.ts +179 -0
  179. package/src/semantic/test/const-reassignment.test.ts +111 -0
  180. package/src/semantic/test/control-flow.test.ts +346 -0
  181. package/src/semantic/test/destructuring.test.ts +185 -0
  182. package/src/semantic/test/duplicate-declarations.test.ts +168 -0
  183. package/src/semantic/test/export-validation.test.ts +111 -0
  184. package/src/semantic/test/fixtures/math.ts +31 -0
  185. package/src/semantic/test/imports.test.ts +148 -0
  186. package/src/semantic/test/json-type.test.ts +68 -0
  187. package/src/semantic/test/literals.test.ts +127 -0
  188. package/src/semantic/test/model-validation.test.ts +179 -0
  189. package/src/semantic/test/prompt-validation.test.ts +343 -0
  190. package/src/semantic/test/scoping.test.ts +312 -0
  191. package/src/semantic/test/tool-validation.test.ts +306 -0
  192. package/src/semantic/test/ts-type-checking.test.ts +563 -0
  193. package/src/semantic/test/type-constraints.test.ts +111 -0
  194. package/src/semantic/test/type-inference.test.ts +87 -0
  195. package/src/semantic/test/type-validation.test.ts +552 -0
  196. package/src/semantic/test/undefined-variables.test.ts +163 -0
  197. package/src/semantic/ts-block-checker.ts +204 -0
  198. package/src/semantic/ts-signatures.ts +194 -0
  199. package/src/semantic/ts-types.ts +170 -0
  200. package/src/semantic/types.ts +58 -0
  201. package/tests/fixtures/conditional-logic.vibe +14 -0
  202. package/tests/fixtures/function-call.vibe +16 -0
  203. package/tests/fixtures/imports/cycle-detection/a.vibe +6 -0
  204. package/tests/fixtures/imports/cycle-detection/b.vibe +5 -0
  205. package/tests/fixtures/imports/cycle-detection/main.vibe +3 -0
  206. package/tests/fixtures/imports/module-isolation/main-b.vibe +8 -0
  207. package/tests/fixtures/imports/module-isolation/main.vibe +9 -0
  208. package/tests/fixtures/imports/module-isolation/moduleA.vibe +6 -0
  209. package/tests/fixtures/imports/module-isolation/moduleB.vibe +6 -0
  210. package/tests/fixtures/imports/nested-import/helper.vibe +6 -0
  211. package/tests/fixtures/imports/nested-import/main.vibe +3 -0
  212. package/tests/fixtures/imports/nested-import/utils.ts +3 -0
  213. package/tests/fixtures/imports/nested-isolation/file2.vibe +15 -0
  214. package/tests/fixtures/imports/nested-isolation/file3.vibe +10 -0
  215. package/tests/fixtures/imports/nested-isolation/main.vibe +21 -0
  216. package/tests/fixtures/imports/pure-cycle/a.vibe +5 -0
  217. package/tests/fixtures/imports/pure-cycle/b.vibe +5 -0
  218. package/tests/fixtures/imports/pure-cycle/main.vibe +3 -0
  219. package/tests/fixtures/imports/ts-boolean/checks.ts +14 -0
  220. package/tests/fixtures/imports/ts-boolean/main.vibe +10 -0
  221. package/tests/fixtures/imports/ts-boolean/type-mismatch.vibe +5 -0
  222. package/tests/fixtures/imports/ts-boolean/use-constant.vibe +18 -0
  223. package/tests/fixtures/imports/ts-error-handling/helpers.ts +42 -0
  224. package/tests/fixtures/imports/ts-error-handling/main.vibe +5 -0
  225. package/tests/fixtures/imports/ts-import/main.vibe +4 -0
  226. package/tests/fixtures/imports/ts-import/math.ts +9 -0
  227. package/tests/fixtures/imports/ts-variables/call-non-function.vibe +5 -0
  228. package/tests/fixtures/imports/ts-variables/data.ts +10 -0
  229. package/tests/fixtures/imports/ts-variables/import-json.vibe +5 -0
  230. package/tests/fixtures/imports/ts-variables/import-type-mismatch.vibe +5 -0
  231. package/tests/fixtures/imports/ts-variables/import-variable.vibe +5 -0
  232. package/tests/fixtures/imports/vibe-import/greet.vibe +5 -0
  233. package/tests/fixtures/imports/vibe-import/main.vibe +3 -0
  234. package/tests/fixtures/multiple-ai-calls.vibe +10 -0
  235. package/tests/fixtures/simple-greeting.vibe +6 -0
  236. package/tests/fixtures/template-literals.vibe +11 -0
  237. package/tests/integration/basic-ai/basic-ai.integration.test.ts +166 -0
  238. package/tests/integration/basic-ai/basic-ai.vibe +12 -0
  239. package/tests/integration/bug-fix/bug-fix.integration.test.ts +201 -0
  240. package/tests/integration/bug-fix/buggy-code.ts +22 -0
  241. package/tests/integration/bug-fix/fix-bug.vibe +21 -0
  242. package/tests/integration/compress/compress.integration.test.ts +206 -0
  243. package/tests/integration/destructuring/destructuring.integration.test.ts +92 -0
  244. package/tests/integration/hello-world-translator/hello-world-translator.integration.test.ts +61 -0
  245. package/tests/integration/line-annotator/context-modes.integration.test.ts +261 -0
  246. package/tests/integration/line-annotator/line-annotator.integration.test.ts +148 -0
  247. package/tests/integration/multi-feature/cumulative-sum.integration.test.ts +75 -0
  248. package/tests/integration/multi-feature/number-analyzer.integration.test.ts +191 -0
  249. package/tests/integration/multi-feature/number-analyzer.vibe +59 -0
  250. package/tests/integration/tool-calls/tool-calls.integration.test.ts +93 -0
@@ -0,0 +1,230 @@
1
+ import { describe, expect, test } from 'bun:test';
2
+ import { parse } from '../../parse';
3
+ import { ParserError, LexerError } from '../../../errors';
4
+
5
+ describe('Error Locations', () => {
6
+ // ============================================================================
7
+ // Parser error locations
8
+ // ============================================================================
9
+
10
+ test('missing closing brace reports error', () => {
11
+ try {
12
+ parse(`
13
+ let x = "first"
14
+ let y = "second"
15
+ if condition {
16
+ let z = "inside"
17
+ `);
18
+ expect.unreachable('Should have thrown');
19
+ } catch (e) {
20
+ expect(e).toBeInstanceOf(ParserError);
21
+ const err = e as ParserError;
22
+ // EOF token may not have line info, but error should exist
23
+ expect(err.location).toBeDefined();
24
+ }
25
+ });
26
+
27
+ test('unexpected token reports correct line and column', () => {
28
+ try {
29
+ parse(`
30
+ let a = "one"
31
+ let b = "two"
32
+ let = "missing identifier"
33
+ `);
34
+ expect.unreachable('Should have thrown');
35
+ } catch (e) {
36
+ expect(e).toBeInstanceOf(ParserError);
37
+ const err = e as ParserError;
38
+ expect(err.location?.line).toBe(4);
39
+ expect(err.location?.column).toBe(5); // position of '='
40
+ }
41
+ });
42
+
43
+ test('missing function body reports correct line', () => {
44
+ try {
45
+ parse(`
46
+ let setup = "before"
47
+
48
+ function broken()
49
+
50
+ let after = "this line"
51
+ `);
52
+ expect.unreachable('Should have thrown');
53
+ } catch (e) {
54
+ expect(e).toBeInstanceOf(ParserError);
55
+ const err = e as ParserError;
56
+ expect(err.location?.line).toBe(6); // 'let' on line 6 instead of '{'
57
+ }
58
+ });
59
+
60
+ test('invalid expression in nested block reports correct line', () => {
61
+ try {
62
+ parse(`
63
+ function outer() {
64
+ let a = "first"
65
+ if condition {
66
+ let b = = "double equals"
67
+ }
68
+ }
69
+ `);
70
+ expect.unreachable('Should have thrown');
71
+ } catch (e) {
72
+ expect(e).toBeInstanceOf(ParserError);
73
+ const err = e as ParserError;
74
+ expect(err.location?.line).toBe(5);
75
+ }
76
+ });
77
+
78
+ test('unclosed string in call reports correct line', () => {
79
+ try {
80
+ parse(`
81
+ let x = "before"
82
+ let y = "middle"
83
+ foo("unclosed
84
+ let z = "after"
85
+ `);
86
+ expect.unreachable('Should have thrown');
87
+ } catch (e) {
88
+ // Unclosed string is a lexer error
89
+ expect(e).toBeInstanceOf(LexerError);
90
+ const err = e as LexerError;
91
+ // Lexer reports error on the line after the unclosed string
92
+ expect(err.location?.line).toBe(5);
93
+ }
94
+ });
95
+
96
+ test('missing closing brace in function reports error', () => {
97
+ try {
98
+ parse(`
99
+ function test() {
100
+ let a = "one"
101
+ let b = "two"
102
+ let c = "three"
103
+ `);
104
+ expect.unreachable('Should have thrown');
105
+ } catch (e) {
106
+ expect(e).toBeInstanceOf(ParserError);
107
+ const err = e as ParserError;
108
+ // EOF token may not have line info, but error should exist
109
+ expect(err.location).toBeDefined();
110
+ }
111
+ });
112
+
113
+ // ============================================================================
114
+ // Lexer error locations
115
+ // ============================================================================
116
+
117
+ test('unclosed string reports correct line', () => {
118
+ try {
119
+ parse(`
120
+ let a = "valid"
121
+ let b = "also valid"
122
+ let c = "unclosed
123
+ let d = "never reached"
124
+ `);
125
+ expect.unreachable('Should have thrown');
126
+ } catch (e) {
127
+ expect(e).toBeInstanceOf(LexerError);
128
+ const err = e as LexerError;
129
+ // Lexer reports error on the line after the unclosed string
130
+ expect(err.location?.line).toBe(5);
131
+ }
132
+ });
133
+
134
+ test('unclosed string with single quotes reports correct line', () => {
135
+ try {
136
+ parse(`
137
+ let first = 'ok'
138
+ let second = 'also ok'
139
+ let third = 'not closed
140
+ let fourth = 'never seen'
141
+ `);
142
+ expect.unreachable('Should have thrown');
143
+ } catch (e) {
144
+ expect(e).toBeInstanceOf(LexerError);
145
+ const err = e as LexerError;
146
+ // Lexer reports error on the line after the unclosed string
147
+ expect(err.location?.line).toBe(5);
148
+ }
149
+ });
150
+
151
+ // ============================================================================
152
+ // Error formatting
153
+ // ============================================================================
154
+
155
+ test('format() includes source context', () => {
156
+ try {
157
+ parse(`
158
+ let valid = "ok"
159
+ let broken =
160
+ let after = "never"
161
+ `);
162
+ expect.unreachable('Should have thrown');
163
+ } catch (e) {
164
+ expect(e).toBeInstanceOf(ParserError);
165
+ const err = e as ParserError;
166
+ const formatted = err.format();
167
+ expect(formatted).toContain('[vibe:');
168
+ expect(formatted).toContain('4:'); // line 4 (where 'let after' is)
169
+ }
170
+ });
171
+
172
+ test('format() shows caret pointing to error', () => {
173
+ try {
174
+ parse(`
175
+ let x = "hello"
176
+ let y = "world"
177
+ function () {
178
+ return "missing name"
179
+ }
180
+ `);
181
+ expect.unreachable('Should have thrown');
182
+ } catch (e) {
183
+ expect(e).toBeInstanceOf(ParserError);
184
+ const err = e as ParserError;
185
+ const formatted = err.format();
186
+ expect(formatted).toContain('^'); // caret indicator
187
+ expect(formatted).toContain('|'); // line separator
188
+ }
189
+ });
190
+
191
+ // ============================================================================
192
+ // Column accuracy
193
+ // ============================================================================
194
+
195
+ test('column points to exact token position', () => {
196
+ try {
197
+ parse(`
198
+ let validName = "ok"
199
+ let = "missing identifier"
200
+ `);
201
+ expect.unreachable('Should have thrown');
202
+ } catch (e) {
203
+ expect(e).toBeInstanceOf(ParserError);
204
+ const err = e as ParserError;
205
+ expect(err.location?.line).toBe(3);
206
+ expect(err.location?.column).toBe(8); // position of '=' after spaces
207
+ }
208
+ });
209
+
210
+ test('deeply nested error has correct location', () => {
211
+ try {
212
+ parse(`
213
+ function level1() {
214
+ function level2() {
215
+ if a {
216
+ if b {
217
+ let x = ,
218
+ }
219
+ }
220
+ }
221
+ }
222
+ `);
223
+ expect.unreachable('Should have thrown');
224
+ } catch (e) {
225
+ expect(e).toBeInstanceOf(ParserError);
226
+ const err = e as ParserError;
227
+ expect(err.location?.line).toBe(6);
228
+ }
229
+ });
230
+ });
@@ -0,0 +1,144 @@
1
+ import { describe, expect, test } from 'bun:test';
2
+ import { parse } from '../../parse';
3
+
4
+ describe('Syntax Errors - Invalid Expressions', () => {
5
+ // ============================================================================
6
+ // Invalid call expressions
7
+ // ============================================================================
8
+
9
+ test('call with leading comma', () => {
10
+ expect(() => parse(`
11
+ foo(, "hello")
12
+ `)).toThrow();
13
+ });
14
+
15
+ test('call with trailing comma', () => {
16
+ expect(() => parse(`
17
+ foo("hello",)
18
+ `)).toThrow();
19
+ });
20
+
21
+ test('call with double comma', () => {
22
+ expect(() => parse(`
23
+ foo("a",, "b")
24
+ `)).toThrow();
25
+ });
26
+
27
+ test('call with only comma', () => {
28
+ expect(() => parse(`
29
+ foo(,)
30
+ `)).toThrow();
31
+ });
32
+
33
+ // ============================================================================
34
+ // Invalid function parameters
35
+ // ============================================================================
36
+
37
+ test('function params with leading comma', () => {
38
+ expect(() => parse(`
39
+ function test(, a) {
40
+ return a
41
+ }
42
+ `)).toThrow();
43
+ });
44
+
45
+ test('function params with trailing comma', () => {
46
+ expect(() => parse(`
47
+ function test(a,) {
48
+ return a
49
+ }
50
+ `)).toThrow();
51
+ });
52
+
53
+ test('function params with double comma', () => {
54
+ expect(() => parse(`
55
+ function test(a,, b) {
56
+ return a
57
+ }
58
+ `)).toThrow();
59
+ });
60
+
61
+ // ============================================================================
62
+ // Invalid primary expressions
63
+ // ============================================================================
64
+
65
+ test('empty parentheses as expression', () => {
66
+ expect(() => parse(`
67
+ let x = ()
68
+ `)).toThrow();
69
+ });
70
+
71
+ test('just equals sign', () => {
72
+ expect(() => parse(`
73
+ =
74
+ `)).toThrow();
75
+ });
76
+
77
+ test('just comma', () => {
78
+ expect(() => parse(`
79
+ ,
80
+ `)).toThrow();
81
+ });
82
+
83
+ // ============================================================================
84
+ // Invalid do/vibe expressions
85
+ // ============================================================================
86
+
87
+ test('vibe with equals instead of expression', () => {
88
+ expect(() => parse(`
89
+ let x = vibe =
90
+ `)).toThrow();
91
+ });
92
+
93
+ test('vibe with comma instead of expression', () => {
94
+ expect(() => parse(`
95
+ let x = vibe ,
96
+ `)).toThrow();
97
+ });
98
+
99
+ test('vibe with closing paren', () => {
100
+ expect(() => parse(`
101
+ let x = vibe )
102
+ `)).toThrow();
103
+ });
104
+
105
+ // ============================================================================
106
+ // Invalid if conditions
107
+ // ============================================================================
108
+
109
+ test('if with empty condition', () => {
110
+ expect(() => parse(`
111
+ if {
112
+ let x = "yes"
113
+ }
114
+ `)).toThrow();
115
+ });
116
+
117
+ test('if with equals as condition', () => {
118
+ expect(() => parse(`
119
+ if = {
120
+ let x = "yes"
121
+ }
122
+ `)).toThrow();
123
+ });
124
+
125
+ // ============================================================================
126
+ // Invalid return expressions
127
+ // ============================================================================
128
+
129
+ test('return with comma', () => {
130
+ expect(() => parse(`
131
+ function test() {
132
+ return ,
133
+ }
134
+ `)).toThrow();
135
+ });
136
+
137
+ test('return with only equals', () => {
138
+ expect(() => parse(`
139
+ function test() {
140
+ return =
141
+ }
142
+ `)).toThrow();
143
+ });
144
+ });
@@ -0,0 +1,126 @@
1
+ import { describe, expect, test } from 'bun:test';
2
+ import { parse } from '../../parse';
3
+
4
+ describe('Syntax Errors - Missing Tokens', () => {
5
+ // ============================================================================
6
+ // const declaration
7
+ // ============================================================================
8
+
9
+ test('const missing equals and initializer', () => {
10
+ expect(() => parse(`
11
+ const x
12
+ `)).toThrow();
13
+ });
14
+
15
+ test('const missing initializer after equals', () => {
16
+ expect(() => parse(`
17
+ const x =
18
+ `)).toThrow();
19
+ });
20
+
21
+ // ============================================================================
22
+ // let declaration
23
+ // ============================================================================
24
+
25
+ test('let missing initializer after equals', () => {
26
+ expect(() => parse(`
27
+ let x =
28
+ `)).toThrow();
29
+ });
30
+
31
+ // ============================================================================
32
+ // function declaration
33
+ // ============================================================================
34
+
35
+ test('function missing closing paren', () => {
36
+ expect(() => parse(`
37
+ function foo(
38
+ `)).toThrow();
39
+ });
40
+
41
+ test('function missing body', () => {
42
+ expect(() => parse(`
43
+ function foo()
44
+ `)).toThrow();
45
+ });
46
+
47
+ test('function with params missing closing paren', () => {
48
+ expect(() => parse(`
49
+ function greet(name
50
+ `)).toThrow();
51
+ });
52
+
53
+ test('function missing opening paren', () => {
54
+ expect(() => parse(`
55
+ function foo {
56
+ return "hello"
57
+ }
58
+ `)).toThrow();
59
+ });
60
+
61
+ // ============================================================================
62
+ // if statement
63
+ // ============================================================================
64
+
65
+ test('if missing block', () => {
66
+ expect(() => parse(`
67
+ if true
68
+ `)).toThrow();
69
+ });
70
+
71
+ test('if with else missing block', () => {
72
+ expect(() => parse(`
73
+ if true {
74
+ let x = "yes"
75
+ } else
76
+ `)).toThrow();
77
+ });
78
+
79
+ // ============================================================================
80
+ // return statement
81
+ // ============================================================================
82
+
83
+ test('return with incomplete expression', () => {
84
+ expect(() => parse(`
85
+ function test() {
86
+ return =
87
+ }
88
+ `)).toThrow();
89
+ });
90
+
91
+ // ============================================================================
92
+ // vibe expression
93
+ // ============================================================================
94
+
95
+ test('vibe missing prompt', () => {
96
+ expect(() => parse(`
97
+ let x = do
98
+ `)).toThrow();
99
+ });
100
+
101
+ // ============================================================================
102
+ // vibe expression
103
+ // ============================================================================
104
+
105
+ test('vibe missing prompt', () => {
106
+ expect(() => parse(`
107
+ let x = vibe
108
+ `)).toThrow();
109
+ });
110
+
111
+ // ============================================================================
112
+ // call expression
113
+ // ============================================================================
114
+
115
+ test('call missing closing paren', () => {
116
+ expect(() => parse(`
117
+ foo(
118
+ `)).toThrow();
119
+ });
120
+
121
+ test('call with args missing closing paren', () => {
122
+ expect(() => parse(`
123
+ greet("hello"
124
+ `)).toThrow();
125
+ });
126
+ });
@@ -0,0 +1,185 @@
1
+ import { describe, expect, test } from 'bun:test';
2
+ import { parse } from '../../parse';
3
+
4
+ describe('Syntax Errors - Model Declaration', () => {
5
+ // ============================================================================
6
+ // Missing model components
7
+ // ============================================================================
8
+
9
+ test('model missing name', () => {
10
+ expect(() => parse(`
11
+ model = {
12
+ name: "test"
13
+ }
14
+ `)).toThrow();
15
+ });
16
+
17
+ test('model missing equals sign', () => {
18
+ expect(() => parse(`
19
+ model myModel {
20
+ name: "test"
21
+ }
22
+ `)).toThrow();
23
+ });
24
+
25
+ test('model missing object literal', () => {
26
+ expect(() => parse(`
27
+ model myModel =
28
+ `)).toThrow();
29
+ });
30
+
31
+ test('model with string instead of object', () => {
32
+ expect(() => parse(`
33
+ model myModel = "not an object"
34
+ `)).toThrow();
35
+ });
36
+
37
+ test('model with identifier instead of object', () => {
38
+ expect(() => parse(`
39
+ model myModel = otherModel
40
+ `)).toThrow();
41
+ });
42
+
43
+ // ============================================================================
44
+ // Object literal errors
45
+ // ============================================================================
46
+
47
+ test('model with unclosed brace', () => {
48
+ expect(() => parse(`
49
+ model myModel = {
50
+ name: "test"
51
+ `)).toThrow();
52
+ });
53
+
54
+ test('model with only opening brace', () => {
55
+ expect(() => parse(`
56
+ model myModel = {
57
+ `)).toThrow();
58
+ });
59
+
60
+ test('model missing opening brace', () => {
61
+ expect(() => parse(`
62
+ model myModel = name: "test" }
63
+ `)).toThrow();
64
+ });
65
+
66
+ // ============================================================================
67
+ // Property errors
68
+ // ============================================================================
69
+
70
+ test('property missing colon', () => {
71
+ expect(() => parse(`
72
+ model myModel = {
73
+ name "test"
74
+ }
75
+ `)).toThrow();
76
+ });
77
+
78
+ test('property missing value', () => {
79
+ expect(() => parse(`
80
+ model myModel = {
81
+ name:
82
+ }
83
+ `)).toThrow();
84
+ });
85
+
86
+ test('property with trailing comma only', () => {
87
+ expect(() => parse(`
88
+ model myModel = {
89
+ ,
90
+ }
91
+ `)).toThrow();
92
+ });
93
+
94
+ test('property with double colon', () => {
95
+ expect(() => parse(`
96
+ model myModel = {
97
+ name:: "test"
98
+ }
99
+ `)).toThrow();
100
+ });
101
+
102
+ test('property with equals instead of colon', () => {
103
+ expect(() => parse(`
104
+ model myModel = {
105
+ name = "test"
106
+ }
107
+ `)).toThrow();
108
+ });
109
+
110
+ test('property key as string literal', () => {
111
+ expect(() => parse(`
112
+ model myModel = {
113
+ "name": "test"
114
+ }
115
+ `)).toThrow();
116
+ });
117
+
118
+ test('property with missing key', () => {
119
+ expect(() => parse(`
120
+ model myModel = {
121
+ : "test"
122
+ }
123
+ `)).toThrow();
124
+ });
125
+
126
+ // ============================================================================
127
+ // Multiple properties errors
128
+ // ============================================================================
129
+
130
+ test('properties missing comma separator', () => {
131
+ expect(() => parse(`
132
+ model myModel = {
133
+ name: "test"
134
+ apiKey: "key"
135
+ }
136
+ `)).toThrow();
137
+ });
138
+
139
+ test('properties with double comma', () => {
140
+ expect(() => parse(`
141
+ model myModel = {
142
+ name: "test",,
143
+ apiKey: "key"
144
+ }
145
+ `)).toThrow();
146
+ });
147
+
148
+ test('trailing comma without next property', () => {
149
+ expect(() => parse(`
150
+ model myModel = {
151
+ name: "test",
152
+ }
153
+ `)).toThrow();
154
+ });
155
+
156
+ // ============================================================================
157
+ // Model keyword misuse
158
+ // ============================================================================
159
+
160
+ test('model as variable name', () => {
161
+ expect(() => parse(`
162
+ let model = "test"
163
+ `)).toThrow();
164
+ });
165
+
166
+ test('nested model in property', () => {
167
+ expect(() => parse(`
168
+ model outer = {
169
+ inner: model nested = {}
170
+ }
171
+ `)).toThrow();
172
+ });
173
+
174
+ // ============================================================================
175
+ // Model with invalid property values
176
+ // ============================================================================
177
+
178
+ test('model property with unclosed string', () => {
179
+ expect(() => parse(`
180
+ model myModel = {
181
+ name: "unclosed
182
+ }
183
+ `)).toThrow();
184
+ });
185
+ });