kimchilang 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/.github/workflows/ci.yml +66 -0
- package/README.md +1547 -0
- package/create-kimchi-app/README.md +44 -0
- package/create-kimchi-app/index.js +214 -0
- package/create-kimchi-app/package.json +22 -0
- package/editors/README.md +121 -0
- package/editors/sublime/KimchiLang.sublime-syntax +138 -0
- package/editors/vscode/README.md +90 -0
- package/editors/vscode/kimchilang-1.1.0.vsix +0 -0
- package/editors/vscode/language-configuration.json +37 -0
- package/editors/vscode/package.json +55 -0
- package/editors/vscode/src/extension.js +354 -0
- package/editors/vscode/syntaxes/kimchi.tmLanguage.json +215 -0
- package/examples/api/client.km +36 -0
- package/examples/async_pipe.km +58 -0
- package/examples/basic.kimchi +109 -0
- package/examples/cli_framework/README.md +92 -0
- package/examples/cli_framework/calculator.km +61 -0
- package/examples/cli_framework/deploy.km +126 -0
- package/examples/cli_framework/greeter.km +26 -0
- package/examples/config.static +27 -0
- package/examples/config.static.js +10 -0
- package/examples/env_test.km +37 -0
- package/examples/fibonacci.kimchi +17 -0
- package/examples/greeter.km +15 -0
- package/examples/hello.js +1 -0
- package/examples/hello.kimchi +3 -0
- package/examples/js_interop.km +42 -0
- package/examples/logger_example.km +34 -0
- package/examples/memo_fibonacci.km +17 -0
- package/examples/myapp/lib/http.js +14 -0
- package/examples/myapp/lib/http.km +16 -0
- package/examples/myapp/main.km +16 -0
- package/examples/myapp/main_with_mock.km +42 -0
- package/examples/myapp/services/api.js +18 -0
- package/examples/myapp/services/api.km +18 -0
- package/examples/new_features.kimchi +52 -0
- package/examples/project_example.static +20 -0
- package/examples/readme_examples.km +240 -0
- package/examples/reduce_pattern_match.km +85 -0
- package/examples/regex_match.km +46 -0
- package/examples/sample.js +45 -0
- package/examples/sample.km +39 -0
- package/examples/secrets.static +35 -0
- package/examples/secrets.static.js +30 -0
- package/examples/shell-example.mjs +144 -0
- package/examples/shell_example.km +19 -0
- package/examples/stdlib_test.km +22 -0
- package/examples/test_example.km +69 -0
- package/examples/testing/README.md +88 -0
- package/examples/testing/http_client.km +18 -0
- package/examples/testing/math.km +48 -0
- package/examples/testing/math.test.km +93 -0
- package/examples/testing/user_service.km +29 -0
- package/examples/testing/user_service.test.km +72 -0
- package/examples/use-config.mjs +141 -0
- package/examples/use_config.km +13 -0
- package/install.sh +59 -0
- package/package.json +29 -0
- package/pantry/acorn/index.km +1 -0
- package/pantry/is_number/index.km +1 -0
- package/pantry/is_odd/index.km +2 -0
- package/project.static +6 -0
- package/src/cli.js +1245 -0
- package/src/generator.js +1241 -0
- package/src/index.js +141 -0
- package/src/js2km.js +568 -0
- package/src/lexer.js +822 -0
- package/src/linter.js +810 -0
- package/src/package-manager.js +307 -0
- package/src/parser.js +1876 -0
- package/src/static-parser.js +500 -0
- package/src/typechecker.js +950 -0
- package/stdlib/array.km +0 -0
- package/stdlib/bitwise.km +38 -0
- package/stdlib/console.km +49 -0
- package/stdlib/date.km +97 -0
- package/stdlib/function.km +44 -0
- package/stdlib/http.km +197 -0
- package/stdlib/http.md +333 -0
- package/stdlib/index.km +26 -0
- package/stdlib/json.km +17 -0
- package/stdlib/logger.js +114 -0
- package/stdlib/logger.km +104 -0
- package/stdlib/math.km +120 -0
- package/stdlib/object.km +41 -0
- package/stdlib/promise.km +33 -0
- package/stdlib/string.km +93 -0
- package/stdlib/testing.md +265 -0
- package/test/test.js +599 -0
package/stdlib/object.km
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// KimchiLang Standard Library - Object Functions
|
|
2
|
+
|
|
3
|
+
expose fn _describe() {
|
|
4
|
+
return "Object utilities: keys, values, entries, merge, etc."
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
expose fn keys(obj) {
|
|
8
|
+
return Object.keys(obj)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
expose fn values(obj) {
|
|
12
|
+
return Object.values(obj)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
expose fn entries(obj) {
|
|
16
|
+
return Object.entries(obj)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
expose fn fromEntries(arr) {
|
|
20
|
+
return Object.fromEntries(arr)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
expose fn has(obj, key) {
|
|
24
|
+
return Object.hasOwn(obj, key)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
expose fn freeze(obj) {
|
|
28
|
+
return Object.freeze(obj)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
expose fn isEmpty(obj) {
|
|
32
|
+
return Object.keys(obj).length == 0
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
expose fn size(obj) {
|
|
36
|
+
return Object.keys(obj).length
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
expose fn assign(target, source) {
|
|
40
|
+
return Object.assign(target, source)
|
|
41
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// KimchiLang Standard Library - Promise Functions
|
|
2
|
+
|
|
3
|
+
expose fn _describe() {
|
|
4
|
+
return "Promise/async utilities: all, race, resolve, reject, delay"
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
expose fn resolve(value) {
|
|
8
|
+
return Promise.resolve(value)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
expose fn reject(reason) {
|
|
12
|
+
return Promise.reject(reason)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
expose fn all(promises) {
|
|
16
|
+
return Promise.all(promises)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
expose fn allSettled(promises) {
|
|
20
|
+
return Promise.allSettled(promises)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
expose fn race(promises) {
|
|
24
|
+
return Promise.race(promises)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
expose fn any(promises) {
|
|
28
|
+
return Promise.any(promises)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
expose fn delay(ms) {
|
|
32
|
+
return new Promise((res) => setTimeout(res, ms))
|
|
33
|
+
}
|
package/stdlib/string.km
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// KimchiLang Standard Library - String Functions
|
|
2
|
+
|
|
3
|
+
expose fn _describe() {
|
|
4
|
+
return "String utilities: split, trim, replace, case conversion, etc."
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
expose fn split(str, separator) {
|
|
8
|
+
return str.split(separator)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
expose fn trim(str) {
|
|
12
|
+
return str.trim()
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
expose fn trimStart(str) {
|
|
16
|
+
return str.trimStart()
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
expose fn trimEnd(str) {
|
|
20
|
+
return str.trimEnd()
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
expose fn toUpperCase(str) {
|
|
24
|
+
return str.toUpperCase()
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
expose fn toLowerCase(str) {
|
|
28
|
+
return str.toLowerCase()
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
expose fn startsWith(str, prefix) {
|
|
32
|
+
return str.startsWith(prefix)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
expose fn endsWith(str, suffix) {
|
|
36
|
+
return str.endsWith(suffix)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
expose fn includes(str, substring) {
|
|
40
|
+
return str.includes(substring)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
expose fn indexOf(str, substring) {
|
|
44
|
+
return str.indexOf(substring)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
expose fn replace(str, search, replacement) {
|
|
48
|
+
return str.replace(search, replacement)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
expose fn replaceAll(str, search, replacement) {
|
|
52
|
+
return str.replaceAll(search, replacement)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
expose fn slice(str, start, end) {
|
|
56
|
+
return str.slice(start, end)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
expose fn charAt(str, index) {
|
|
60
|
+
return str.charAt(index)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
expose fn padStart(str, length, padStr) {
|
|
64
|
+
return str.padStart(length, padStr)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
expose fn padEnd(str, length, padStr) {
|
|
68
|
+
return str.padEnd(length, padStr)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
expose fn repeat(str, count) {
|
|
72
|
+
return str.repeat(count)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
expose fn length(str) {
|
|
76
|
+
return str.length
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
expose fn isEmpty(str) {
|
|
80
|
+
return str.length == 0
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
expose fn isBlank(str) {
|
|
84
|
+
return str.trim().length == 0
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
expose fn toChars(str) {
|
|
88
|
+
return str.split("")
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
expose fn toLines(str) {
|
|
92
|
+
return str.split("\n")
|
|
93
|
+
}
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
# KimchiLang Testing Framework
|
|
2
|
+
|
|
3
|
+
KimchiLang has a built-in testing framework that makes it easy to write and run tests without any external dependencies.
|
|
4
|
+
|
|
5
|
+
## Running Tests
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
kimchi test myfile.km
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Syntax
|
|
12
|
+
|
|
13
|
+
### `test`
|
|
14
|
+
|
|
15
|
+
Define a single test case:
|
|
16
|
+
|
|
17
|
+
```kimchi
|
|
18
|
+
test "test name" {
|
|
19
|
+
// test code here
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### `describe`
|
|
24
|
+
|
|
25
|
+
Group related tests together:
|
|
26
|
+
|
|
27
|
+
```kimchi
|
|
28
|
+
describe "Group name" {
|
|
29
|
+
test "first test" {
|
|
30
|
+
// ...
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
test "second test" {
|
|
34
|
+
// ...
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Describe blocks can be nested:
|
|
40
|
+
|
|
41
|
+
```kimchi
|
|
42
|
+
describe "Math operations" {
|
|
43
|
+
describe "Addition" {
|
|
44
|
+
test "adds positive numbers" {
|
|
45
|
+
expect(1 + 2).toBe(3)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
describe "Subtraction" {
|
|
50
|
+
test "subtracts numbers" {
|
|
51
|
+
expect(5 - 3).toBe(2)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### `expect`
|
|
58
|
+
|
|
59
|
+
Make assertions about values:
|
|
60
|
+
|
|
61
|
+
```kimchi
|
|
62
|
+
expect(actual).matcher(expected)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### `assert`
|
|
66
|
+
|
|
67
|
+
Simple assertion with optional message:
|
|
68
|
+
|
|
69
|
+
```kimchi
|
|
70
|
+
assert condition, "Error message if condition is false"
|
|
71
|
+
assert 1 + 1 == 2
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Matchers
|
|
75
|
+
|
|
76
|
+
### `toBe(expected)`
|
|
77
|
+
|
|
78
|
+
Strict equality check (`===`):
|
|
79
|
+
|
|
80
|
+
```kimchi
|
|
81
|
+
expect(5).toBe(5)
|
|
82
|
+
expect("hello").toBe("hello")
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### `toEqual(expected)`
|
|
86
|
+
|
|
87
|
+
Deep equality check (compares objects/arrays by value):
|
|
88
|
+
|
|
89
|
+
```kimchi
|
|
90
|
+
expect({ a: 1 }).toEqual({ a: 1 })
|
|
91
|
+
expect([1, 2, 3]).toEqual([1, 2, 3])
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### `toContain(item)`
|
|
95
|
+
|
|
96
|
+
Check if array or string contains an item:
|
|
97
|
+
|
|
98
|
+
```kimchi
|
|
99
|
+
expect([1, 2, 3]).toContain(2)
|
|
100
|
+
expect("hello world").toContain("world")
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### `toBeNull()`
|
|
104
|
+
|
|
105
|
+
Check if value is null:
|
|
106
|
+
|
|
107
|
+
```kimchi
|
|
108
|
+
expect(null).toBeNull()
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### `toBeTruthy()`
|
|
112
|
+
|
|
113
|
+
Check if value is truthy:
|
|
114
|
+
|
|
115
|
+
```kimchi
|
|
116
|
+
expect(true).toBeTruthy()
|
|
117
|
+
expect("hello").toBeTruthy()
|
|
118
|
+
expect(1).toBeTruthy()
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### `toBeFalsy()`
|
|
122
|
+
|
|
123
|
+
Check if value is falsy:
|
|
124
|
+
|
|
125
|
+
```kimchi
|
|
126
|
+
expect(false).toBeFalsy()
|
|
127
|
+
expect(null).toBeFalsy()
|
|
128
|
+
expect(0).toBeFalsy()
|
|
129
|
+
expect("").toBeFalsy()
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### `toBeGreaterThan(n)`
|
|
133
|
+
|
|
134
|
+
Check if value is greater than n:
|
|
135
|
+
|
|
136
|
+
```kimchi
|
|
137
|
+
expect(10).toBeGreaterThan(5)
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### `toBeLessThan(n)`
|
|
141
|
+
|
|
142
|
+
Check if value is less than n:
|
|
143
|
+
|
|
144
|
+
```kimchi
|
|
145
|
+
expect(3).toBeLessThan(7)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### `toHaveLength(n)`
|
|
149
|
+
|
|
150
|
+
Check array or string length:
|
|
151
|
+
|
|
152
|
+
```kimchi
|
|
153
|
+
expect([1, 2, 3]).toHaveLength(3)
|
|
154
|
+
expect("hello").toHaveLength(5)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### `toMatch(pattern)`
|
|
158
|
+
|
|
159
|
+
Check if string matches a regex pattern:
|
|
160
|
+
|
|
161
|
+
```kimchi
|
|
162
|
+
expect("hello@example.com").toMatch(/\w+@\w+\.\w+/)
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### `toThrow(message?)`
|
|
166
|
+
|
|
167
|
+
Check if a function throws an error:
|
|
168
|
+
|
|
169
|
+
```kimchi
|
|
170
|
+
dec throwingFn = () => {
|
|
171
|
+
throw error("Something went wrong")
|
|
172
|
+
}
|
|
173
|
+
expect(throwingFn).toThrow()
|
|
174
|
+
expect(throwingFn).toThrow("Something went wrong")
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Complete Example
|
|
178
|
+
|
|
179
|
+
```kimchi
|
|
180
|
+
// math.test.km
|
|
181
|
+
|
|
182
|
+
fn add(a, b) {
|
|
183
|
+
return a + b
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
fn divide(a, b) {
|
|
187
|
+
if b == 0 {
|
|
188
|
+
throw error("Cannot divide by zero")
|
|
189
|
+
}
|
|
190
|
+
return a / b
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
describe "Math functions" {
|
|
194
|
+
describe "add" {
|
|
195
|
+
test "adds two positive numbers" {
|
|
196
|
+
expect(add(2, 3)).toBe(5)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
test "adds negative numbers" {
|
|
200
|
+
expect(add(-1, -2)).toBe(-3)
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
test "adds zero" {
|
|
204
|
+
expect(add(5, 0)).toBe(5)
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
describe "divide" {
|
|
209
|
+
test "divides two numbers" {
|
|
210
|
+
expect(divide(10, 2)).toBe(5)
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
test "throws on division by zero" {
|
|
214
|
+
expect(() => divide(10, 0)).toThrow("Cannot divide by zero")
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Using assert for simple checks
|
|
220
|
+
test "basic assertions" {
|
|
221
|
+
assert 1 + 1 == 2, "Basic math should work"
|
|
222
|
+
assert true
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Run with:
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
kimchi test math.test.km
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Output:
|
|
233
|
+
|
|
234
|
+
```
|
|
235
|
+
Math functions
|
|
236
|
+
add
|
|
237
|
+
✓ adds two positive numbers
|
|
238
|
+
✓ adds negative numbers
|
|
239
|
+
✓ adds zero
|
|
240
|
+
divide
|
|
241
|
+
✓ divides two numbers
|
|
242
|
+
✓ throws on division by zero
|
|
243
|
+
✓ basic assertions
|
|
244
|
+
|
|
245
|
+
6 tests, 6 passed, 0 failed
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
## Async Tests
|
|
249
|
+
|
|
250
|
+
Tests automatically support async operations:
|
|
251
|
+
|
|
252
|
+
```kimchi
|
|
253
|
+
test "async operation" {
|
|
254
|
+
dec result = await fetchData()
|
|
255
|
+
expect(result.status).toBe(200)
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## Best Practices
|
|
260
|
+
|
|
261
|
+
1. **One assertion per test** - Keep tests focused on a single behavior
|
|
262
|
+
2. **Descriptive names** - Use clear, descriptive test names
|
|
263
|
+
3. **Group related tests** - Use `describe` blocks to organize tests
|
|
264
|
+
4. **Test edge cases** - Include tests for error conditions and boundary values
|
|
265
|
+
5. **Keep tests independent** - Each test should be able to run in isolation
|