jpsx 0.1.16
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/README.md +242 -0
- package/dist/api/__tests__/compile.test.d.ts +2 -0
- package/dist/api/__tests__/compile.test.d.ts.map +1 -0
- package/dist/api/__tests__/compile.test.js +336 -0
- package/dist/api/__tests__/runtime.test.d.ts +2 -0
- package/dist/api/__tests__/runtime.test.d.ts.map +1 -0
- package/dist/api/__tests__/runtime.test.js +275 -0
- package/dist/api/advanced.d.ts +100 -0
- package/dist/api/advanced.d.ts.map +1 -0
- package/dist/api/advanced.js +192 -0
- package/dist/api/benchmark.d.ts +87 -0
- package/dist/api/benchmark.d.ts.map +1 -0
- package/dist/api/benchmark.js +147 -0
- package/dist/api/index.d.ts +88 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +304 -0
- package/dist/ast/types.d.ts +141 -0
- package/dist/ast/types.d.ts.map +1 -0
- package/dist/ast/types.js +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +155 -0
- package/dist/cli.js +30 -0
- package/dist/generator/generator.d.ts +3 -0
- package/dist/generator/generator.d.ts.map +1 -0
- package/dist/generator/generator.js +175 -0
- package/dist/lexer/lexer.d.ts +3 -0
- package/dist/lexer/lexer.d.ts.map +1 -0
- package/dist/lexer/lexer.js +23 -0
- package/dist/lexer/tokenizer.d.ts +9 -0
- package/dist/lexer/tokenizer.d.ts.map +1 -0
- package/dist/lexer/tokenizer.js +240 -0
- package/dist/parser/grammar.d.ts +29 -0
- package/dist/parser/grammar.d.ts.map +1 -0
- package/dist/parser/grammar.js +312 -0
- package/dist/parser/parser.d.ts +4 -0
- package/dist/parser/parser.d.ts.map +1 -0
- package/dist/parser/parser.js +47 -0
- package/dist/runtime/index.d.ts +24 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +108 -0
- package/dist/transformer/transformer.d.ts +3 -0
- package/dist/transformer/transformer.d.ts.map +1 -0
- package/dist/transformer/transformer.js +318 -0
- package/package.json +54 -0
package/README.md
ADDED
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
# JPS (Just Python Script)
|
|
2
|
+
|
|
3
|
+
A Python-like language that compiles to JavaScript, designed to integrate seamlessly with **any frontend framework**.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/jps)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
|
|
8
|
+
## ✨ Features
|
|
9
|
+
|
|
10
|
+
- 🐍 **Python-like syntax** that compiles to clean JavaScript
|
|
11
|
+
- ⚡ **Standalone file integration** - Import `.jps` files like `.jsx/.tsx` files!
|
|
12
|
+
- 🔥 **Hot Module Replacement (HMR)** - Instant feedback during development
|
|
13
|
+
- ⚡ **Zero-config integration** with React, Vue, Svelte, Angular, and more
|
|
14
|
+
- 📦 **Multiple output formats**: ESM, CommonJS, IIFE, UMD
|
|
15
|
+
- 🔌 **Flexible runtime modes**: Inline, external, CDN, or custom
|
|
16
|
+
- 🛠️ **Build tool plugins** for Vite, Webpack, Rollup, esbuild
|
|
17
|
+
- 🌐 **Browser-ready**: Works without any build step
|
|
18
|
+
- 📝 **TypeScript support** with auto-generated declarations
|
|
19
|
+
|
|
20
|
+
## 🚀 Quick Start
|
|
21
|
+
|
|
22
|
+
### Standalone File Integration (⚡ Recommended)
|
|
23
|
+
|
|
24
|
+
Import `.jps` files directly in your code - just like `.tsx` files!
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
# math.jps - a real file!
|
|
28
|
+
def add(a, b):
|
|
29
|
+
return a + b
|
|
30
|
+
|
|
31
|
+
class Calculator:
|
|
32
|
+
def __init__(self):
|
|
33
|
+
self.value = 0
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
// App.tsx - just import and use!
|
|
38
|
+
import { add, Calculator } from './math.jps';
|
|
39
|
+
|
|
40
|
+
const sum = add(10, 20);
|
|
41
|
+
const calc = new Calculator();
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**[See full example →](examples/react-vite-standalone/)**
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
### As a CLI Tool
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# Install globally
|
|
52
|
+
npm install -g jps
|
|
53
|
+
|
|
54
|
+
# Create a new project
|
|
55
|
+
jps init my-project
|
|
56
|
+
cd my-project
|
|
57
|
+
jps run main.jps
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### As a Library (Runtime Compilation)
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# Install in your project
|
|
64
|
+
npm install jps
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
#### React
|
|
68
|
+
|
|
69
|
+
```javascript
|
|
70
|
+
import { compile } from 'jps';
|
|
71
|
+
|
|
72
|
+
function App() {
|
|
73
|
+
const jpsCode = `
|
|
74
|
+
def greet(name):
|
|
75
|
+
return "Hello, " + name
|
|
76
|
+
|
|
77
|
+
print(greet("React"))
|
|
78
|
+
`;
|
|
79
|
+
|
|
80
|
+
const result = compile(jpsCode, {
|
|
81
|
+
format: 'iife',
|
|
82
|
+
runtimeMode: 'inline'
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
eval(result.code); // Outputs: Hello, React
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
#### Vue
|
|
90
|
+
|
|
91
|
+
```vue
|
|
92
|
+
<script setup>
|
|
93
|
+
import { compile } from 'jps';
|
|
94
|
+
const result = compile('print("Hello Vue!")', {
|
|
95
|
+
format: 'iife',
|
|
96
|
+
runtimeMode: 'inline'
|
|
97
|
+
});
|
|
98
|
+
eval(result.code);
|
|
99
|
+
</script>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
#### Browser (No Build Step)
|
|
103
|
+
|
|
104
|
+
```html
|
|
105
|
+
<script type="module">
|
|
106
|
+
import { compile } from 'https://cdn.jsdelivr.net/npm/jps@latest/dist/api/index.js';
|
|
107
|
+
const result = compile('print("Hello Browser!")', {
|
|
108
|
+
format: 'iife',
|
|
109
|
+
runtimeMode: 'inline'
|
|
110
|
+
});
|
|
111
|
+
eval(result.code);
|
|
112
|
+
</script>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## 📖 Documentation
|
|
116
|
+
|
|
117
|
+
- **[Standalone File Integration](docs/STANDALONE_INTEGRATION.md)** - ⚡ Import .jps like .tsx (recommended!)
|
|
118
|
+
- **[Integration Guide](docs/INTEGRATION.md)** - Complete guide for all frameworks
|
|
119
|
+
- **[Quick Start](docs/QUICKSTART.md)** - 30-second integration examples
|
|
120
|
+
- **[Syntax Guide](docs/syntax.md)** - JPS language syntax
|
|
121
|
+
- **[Standard Library](docs/stdlib.md)** - Built-in functions
|
|
122
|
+
- **[API Reference](docs/API.md)** - Programmatic API
|
|
123
|
+
|
|
124
|
+
## 🎯 Use Cases
|
|
125
|
+
|
|
126
|
+
- **Code Playgrounds**: Build interactive Python-like editors
|
|
127
|
+
- **Educational Tools**: Teach Python concepts in the browser
|
|
128
|
+
- **Scripting**: Add Python-like scripting to your JavaScript app
|
|
129
|
+
- **DSL**: Create domain-specific languages with Python syntax
|
|
130
|
+
- **Prototyping**: Rapid development with Python-like syntax
|
|
131
|
+
|
|
132
|
+
## 📦 CLI Commands
|
|
133
|
+
|
|
134
|
+
- `jps build <file>` - Compile JPS to JavaScript
|
|
135
|
+
- `jps run <file>` - Compile and execute
|
|
136
|
+
- `jps watch <file>` - Watch for changes and recompile
|
|
137
|
+
- `jps init [name]` - Initialize a new JPS project
|
|
138
|
+
- `jps doctor` - Verify environment setup
|
|
139
|
+
|
|
140
|
+
## 🔧 Programmatic API
|
|
141
|
+
|
|
142
|
+
```javascript
|
|
143
|
+
import { compile, compileToJS, getRuntime } from 'jps';
|
|
144
|
+
|
|
145
|
+
// Full API with metadata
|
|
146
|
+
const result = compile(source, {
|
|
147
|
+
format: 'esm', // Output format: 'esm' | 'cjs' | 'iife' | 'umd'
|
|
148
|
+
runtimeMode: 'inline', // Runtime: 'inline' | 'external' | 'cdn' | 'none'
|
|
149
|
+
moduleName: 'MyApp', // For IIFE/UMD
|
|
150
|
+
sourceMap: true, // Include source maps
|
|
151
|
+
standalone: false // Bundle everything
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
// Simple API (just returns code)
|
|
155
|
+
const jsCode = compileToJS(source);
|
|
156
|
+
|
|
157
|
+
// Get runtime library code
|
|
158
|
+
const runtime = getRuntime();
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## 🎨 Framework Examples
|
|
162
|
+
|
|
163
|
+
Check out the [examples/](examples/) directory for complete working examples:
|
|
164
|
+
|
|
165
|
+
- **React** - Vite plugin, Webpack loader, runtime compilation
|
|
166
|
+
- **Vue 3** - Composition API integration
|
|
167
|
+
- **Svelte** - Component integration
|
|
168
|
+
- **Angular** - Service integration
|
|
169
|
+
- **Next.js** - App Router and Pages Router
|
|
170
|
+
- **Vanilla Browser** - No build step required
|
|
171
|
+
|
|
172
|
+
## 🛠️ Build Tool Plugins
|
|
173
|
+
|
|
174
|
+
### Vite
|
|
175
|
+
|
|
176
|
+
```javascript
|
|
177
|
+
// vite.config.js
|
|
178
|
+
import { jpsPlugin } from './vite-plugin-jps';
|
|
179
|
+
|
|
180
|
+
export default {
|
|
181
|
+
plugins: [jpsPlugin()]
|
|
182
|
+
};
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Webpack
|
|
186
|
+
|
|
187
|
+
```javascript
|
|
188
|
+
// webpack.config.js
|
|
189
|
+
module.exports = {
|
|
190
|
+
module: {
|
|
191
|
+
rules: [
|
|
192
|
+
{ test: /\.jps$/, use: 'jps-loader' }
|
|
193
|
+
]
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
See [INTEGRATION.md](docs/INTEGRATION.md) for Rollup, esbuild, and more.
|
|
199
|
+
|
|
200
|
+
## 🌟 Why JPS?
|
|
201
|
+
|
|
202
|
+
1. **Framework Agnostic**: Works with React, Vue, Svelte, Angular, and vanilla JS
|
|
203
|
+
2. **Flexible Output**: Choose the format that fits your needs
|
|
204
|
+
3. **Modern & Production-Ready**: Built with TypeScript, full test coverage
|
|
205
|
+
4. **Developer Friendly**: Simple API, great error messages, comprehensive docs
|
|
206
|
+
5. **Lightweight**: Minimal dependencies, tree-shakeable
|
|
207
|
+
|
|
208
|
+
## 🏗️ Development
|
|
209
|
+
|
|
210
|
+
Prerequisites: Node.js 18+
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
# Clone the repository
|
|
214
|
+
git clone https://github.com/your-repo/jps.git
|
|
215
|
+
cd jps
|
|
216
|
+
|
|
217
|
+
# Install dependencies
|
|
218
|
+
npm install
|
|
219
|
+
|
|
220
|
+
# Build the project
|
|
221
|
+
npm run build
|
|
222
|
+
|
|
223
|
+
# Run tests
|
|
224
|
+
npm test
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## 📄 License
|
|
228
|
+
|
|
229
|
+
ISC - See [LICENSE](LICENSE) file for details
|
|
230
|
+
|
|
231
|
+
## 🤝 Contributing
|
|
232
|
+
|
|
233
|
+
Contributions are welcome! Please read our contributing guidelines first.
|
|
234
|
+
|
|
235
|
+
## 📮 Support
|
|
236
|
+
|
|
237
|
+
- **Issues**: [GitHub Issues](https://github.com/your-repo/jps/issues)
|
|
238
|
+
- **Discussions**: [GitHub Discussions](https://github.com/your-repo/jps/discussions)
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
**Made with ❤️ by Loaii abdalslam**
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile.test.d.ts","sourceRoot":"","sources":["../../../src/api/__tests__/compile.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
import { compile, compileToJS, getRuntime } from "../index.js";
|
|
2
|
+
describe("compile() - Basic Functionality", () => {
|
|
3
|
+
test("should compile simple JPS code", () => {
|
|
4
|
+
const source = 'print("Hello World")';
|
|
5
|
+
const result = compile(source);
|
|
6
|
+
expect(result.code).toBeDefined();
|
|
7
|
+
expect(result.code).toContain("print");
|
|
8
|
+
expect(result.code).toContain("Hello World");
|
|
9
|
+
});
|
|
10
|
+
test("should return CompileResult with code property", () => {
|
|
11
|
+
const source = 'x = 5';
|
|
12
|
+
const result = compile(source);
|
|
13
|
+
expect(result).toHaveProperty("code");
|
|
14
|
+
expect(typeof result.code).toBe("string");
|
|
15
|
+
});
|
|
16
|
+
test("should compile function definitions", () => {
|
|
17
|
+
const source = `
|
|
18
|
+
def greet(name):
|
|
19
|
+
return "Hello, " + name
|
|
20
|
+
|
|
21
|
+
print(greet("World"))
|
|
22
|
+
`;
|
|
23
|
+
const result = compile(source);
|
|
24
|
+
expect(result.code).toContain("function greet");
|
|
25
|
+
expect(result.code).toContain("return");
|
|
26
|
+
});
|
|
27
|
+
test("should compile list comprehensions", () => {
|
|
28
|
+
const source = '[x * 2 for x in range(5)]';
|
|
29
|
+
const result = compile(source);
|
|
30
|
+
expect(result.code).toContain("for");
|
|
31
|
+
expect(result.code).toContain("push");
|
|
32
|
+
});
|
|
33
|
+
test("should handle multiple statements", () => {
|
|
34
|
+
const source = `
|
|
35
|
+
x = 10
|
|
36
|
+
y = 20
|
|
37
|
+
z = x + y
|
|
38
|
+
print(z)
|
|
39
|
+
`;
|
|
40
|
+
const result = compile(source);
|
|
41
|
+
expect(result.code).toContain("var x");
|
|
42
|
+
expect(result.code).toContain("var y");
|
|
43
|
+
expect(result.code).toContain("var z");
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
describe("compile() - Output Formats", () => {
|
|
47
|
+
const source = 'print("test")';
|
|
48
|
+
test("should generate ESM format by default", () => {
|
|
49
|
+
const result = compile(source);
|
|
50
|
+
expect(result.code).toContain("import");
|
|
51
|
+
});
|
|
52
|
+
test("should generate ESM format when specified", () => {
|
|
53
|
+
const result = compile(source, { format: "esm" });
|
|
54
|
+
expect(result.code).toContain("import {");
|
|
55
|
+
expect(result.code).toMatch(/from\s+['"]/);
|
|
56
|
+
});
|
|
57
|
+
test("should generate CommonJS format", () => {
|
|
58
|
+
const result = compile(source, { format: "cjs" });
|
|
59
|
+
expect(result.code).toContain("require");
|
|
60
|
+
expect(result.code).toMatch(/const\s+{.*}\s*=\s*require/);
|
|
61
|
+
});
|
|
62
|
+
test("should generate IIFE format", () => {
|
|
63
|
+
const result = compile(source, { format: "iife", moduleName: "TestModule" });
|
|
64
|
+
expect(result.code).toContain("(function");
|
|
65
|
+
expect(result.code).toContain("TestModule");
|
|
66
|
+
});
|
|
67
|
+
test("should generate UMD format", () => {
|
|
68
|
+
const result = compile(source, { format: "umd", moduleName: "TestLib" });
|
|
69
|
+
expect(result.code).toContain("define.amd");
|
|
70
|
+
expect(result.code).toContain("module.exports");
|
|
71
|
+
expect(result.code).toContain("TestLib");
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
describe("compile() - Runtime Modes", () => {
|
|
75
|
+
const source = 'print("test")';
|
|
76
|
+
test("should use external runtime by default", () => {
|
|
77
|
+
const result = compile(source);
|
|
78
|
+
expect(result.code).toContain("./jps_runtime.js");
|
|
79
|
+
});
|
|
80
|
+
test("should use external runtime mode", () => {
|
|
81
|
+
const result = compile(source, { runtimeMode: "external" });
|
|
82
|
+
expect(result.code).toContain("jps_runtime");
|
|
83
|
+
});
|
|
84
|
+
test("should inline runtime code", () => {
|
|
85
|
+
const result = compile(source, { runtimeMode: "inline" });
|
|
86
|
+
expect(result.code).toContain("function print");
|
|
87
|
+
expect(result.code).toContain("function range");
|
|
88
|
+
expect(result.code).not.toContain("import");
|
|
89
|
+
});
|
|
90
|
+
test("should use CDN runtime with custom URL", () => {
|
|
91
|
+
const cdnUrl = "https://example.com/runtime.js";
|
|
92
|
+
const result = compile(source, { runtimeMode: "cdn", cdnUrl });
|
|
93
|
+
expect(result.code).toContain(cdnUrl);
|
|
94
|
+
});
|
|
95
|
+
test("should use default CDN URL", () => {
|
|
96
|
+
const result = compile(source, { runtimeMode: "cdn" });
|
|
97
|
+
expect(result.code).toContain("cdn.jsdelivr.net");
|
|
98
|
+
});
|
|
99
|
+
test("should exclude runtime when mode is none", () => {
|
|
100
|
+
const result = compile(source, { runtimeMode: "none" });
|
|
101
|
+
expect(result.code).not.toContain("import");
|
|
102
|
+
expect(result.code).not.toContain("require");
|
|
103
|
+
expect(result.code).not.toContain("function print");
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
describe("compile() - Source Maps", () => {
|
|
107
|
+
const source = 'x = 10';
|
|
108
|
+
test("should not include source map by default", () => {
|
|
109
|
+
const result = compile(source);
|
|
110
|
+
expect(result.map).toBeUndefined();
|
|
111
|
+
expect(result.ast).toBeUndefined();
|
|
112
|
+
});
|
|
113
|
+
test("should include AST when sourceMap is enabled", () => {
|
|
114
|
+
const result = compile(source, { sourceMap: true });
|
|
115
|
+
expect(result.ast).toBeDefined();
|
|
116
|
+
expect(result.ast).toHaveProperty("body");
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
describe("compile() - Module Names", () => {
|
|
120
|
+
const source = 'print("test")';
|
|
121
|
+
test("should use custom module name in IIFE", () => {
|
|
122
|
+
const result = compile(source, {
|
|
123
|
+
format: "iife",
|
|
124
|
+
moduleName: "MyCustomApp",
|
|
125
|
+
runtimeMode: "inline"
|
|
126
|
+
});
|
|
127
|
+
expect(result.code).toContain("MyCustomApp");
|
|
128
|
+
});
|
|
129
|
+
test("should use custom module name in UMD", () => {
|
|
130
|
+
const result = compile(source, {
|
|
131
|
+
format: "umd",
|
|
132
|
+
moduleName: "MyLibrary"
|
|
133
|
+
});
|
|
134
|
+
expect(result.code).toContain("MyLibrary");
|
|
135
|
+
});
|
|
136
|
+
test("should use default module name when not specified", () => {
|
|
137
|
+
const result = compile(source, {
|
|
138
|
+
format: "iife",
|
|
139
|
+
runtimeMode: "inline"
|
|
140
|
+
});
|
|
141
|
+
expect(result.code).toContain("JPSModule");
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
describe("compile() - Error Handling", () => {
|
|
145
|
+
test("should throw error for invalid syntax", () => {
|
|
146
|
+
const source = "def invalid syntax here";
|
|
147
|
+
expect(() => compile(source)).toThrow();
|
|
148
|
+
});
|
|
149
|
+
test("should provide error details", () => {
|
|
150
|
+
const source = "this is not valid jps";
|
|
151
|
+
try {
|
|
152
|
+
compile(source);
|
|
153
|
+
fail("Should have thrown an error");
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
expect(error).toBeDefined();
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
describe("compile() - Complex Programs", () => {
|
|
161
|
+
test("should compile classes", () => {
|
|
162
|
+
const source = `
|
|
163
|
+
class Person:
|
|
164
|
+
def __init__(self, name):
|
|
165
|
+
self.name = name
|
|
166
|
+
|
|
167
|
+
def greet(self):
|
|
168
|
+
return "Hello, " + self.name
|
|
169
|
+
`;
|
|
170
|
+
const result = compile(source);
|
|
171
|
+
expect(result.code).toContain("class Person");
|
|
172
|
+
});
|
|
173
|
+
test("should compile control flow", () => {
|
|
174
|
+
const source = `
|
|
175
|
+
if x > 5:
|
|
176
|
+
print("big")
|
|
177
|
+
else:
|
|
178
|
+
print("small")
|
|
179
|
+
`;
|
|
180
|
+
const result = compile(source);
|
|
181
|
+
expect(result.code).toContain("if");
|
|
182
|
+
expect(result.code).toContain("else");
|
|
183
|
+
});
|
|
184
|
+
test("should compile loops", () => {
|
|
185
|
+
const source = `
|
|
186
|
+
for i in range(10):
|
|
187
|
+
print(i)
|
|
188
|
+
`;
|
|
189
|
+
const result = compile(source);
|
|
190
|
+
expect(result.code).toContain("for");
|
|
191
|
+
});
|
|
192
|
+
test("should compile while loops", () => {
|
|
193
|
+
const source = `
|
|
194
|
+
while x < 10:
|
|
195
|
+
x = x + 1
|
|
196
|
+
`;
|
|
197
|
+
const result = compile(source);
|
|
198
|
+
expect(result.code).toContain("while");
|
|
199
|
+
});
|
|
200
|
+
test("should compile try-catch", () => {
|
|
201
|
+
const source = `
|
|
202
|
+
try:
|
|
203
|
+
risky_operation()
|
|
204
|
+
except:
|
|
205
|
+
print("error")
|
|
206
|
+
`;
|
|
207
|
+
const result = compile(source);
|
|
208
|
+
expect(result.code).toContain("try");
|
|
209
|
+
expect(result.code).toContain("catch");
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
describe("compileToJS() - Simplified API", () => {
|
|
213
|
+
test("should return only JavaScript code as string", () => {
|
|
214
|
+
const source = 'print("test")';
|
|
215
|
+
const result = compileToJS(source);
|
|
216
|
+
expect(typeof result).toBe("string");
|
|
217
|
+
expect(result).toContain("print");
|
|
218
|
+
});
|
|
219
|
+
test("should accept options", () => {
|
|
220
|
+
const source = 'print("test")';
|
|
221
|
+
const result = compileToJS(source, {
|
|
222
|
+
format: "iife",
|
|
223
|
+
runtimeMode: "inline"
|
|
224
|
+
});
|
|
225
|
+
expect(result).toContain("function");
|
|
226
|
+
expect(result).toContain("print");
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
describe("getRuntime()", () => {
|
|
230
|
+
test("should return runtime code as string", () => {
|
|
231
|
+
const runtime = getRuntime();
|
|
232
|
+
expect(typeof runtime).toBe("string");
|
|
233
|
+
expect(runtime).toContain("function print");
|
|
234
|
+
});
|
|
235
|
+
test("should include all runtime functions", () => {
|
|
236
|
+
const runtime = getRuntime();
|
|
237
|
+
expect(runtime).toContain("function print");
|
|
238
|
+
expect(runtime).toContain("function range");
|
|
239
|
+
expect(runtime).toContain("function sum");
|
|
240
|
+
expect(runtime).toContain("function len");
|
|
241
|
+
expect(runtime).toContain("function min");
|
|
242
|
+
expect(runtime).toContain("function max");
|
|
243
|
+
expect(runtime).toContain("function sorted");
|
|
244
|
+
expect(runtime).toContain("function str");
|
|
245
|
+
expect(runtime).toContain("function int");
|
|
246
|
+
expect(runtime).toContain("function float");
|
|
247
|
+
expect(runtime).toContain("function map");
|
|
248
|
+
expect(runtime).toContain("function filter");
|
|
249
|
+
expect(runtime).toContain("function list");
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
describe("Integration Tests - Runtime Execution", () => {
|
|
253
|
+
test("should execute compiled code with inline runtime", () => {
|
|
254
|
+
const source = `
|
|
255
|
+
def add(a, b):
|
|
256
|
+
return a + b
|
|
257
|
+
|
|
258
|
+
result = add(2, 3)
|
|
259
|
+
`;
|
|
260
|
+
const compiled = compile(source, {
|
|
261
|
+
format: "iife",
|
|
262
|
+
runtimeMode: "inline",
|
|
263
|
+
moduleName: "TestApp"
|
|
264
|
+
});
|
|
265
|
+
// This would need actual execution in a real test
|
|
266
|
+
expect(compiled.code).toContain("function add");
|
|
267
|
+
});
|
|
268
|
+
test("should handle runtime functions in compiled code", () => {
|
|
269
|
+
const source = `
|
|
270
|
+
numbers = range(5)
|
|
271
|
+
total = sum(numbers)
|
|
272
|
+
print(total)
|
|
273
|
+
`;
|
|
274
|
+
const compiled = compile(source, {
|
|
275
|
+
format: "iife",
|
|
276
|
+
runtimeMode: "inline"
|
|
277
|
+
});
|
|
278
|
+
expect(compiled.code).toContain("range");
|
|
279
|
+
expect(compiled.code).toContain("sum");
|
|
280
|
+
expect(compiled.code).toContain("print");
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
describe("Edge Cases", () => {
|
|
284
|
+
test("should handle empty source", () => {
|
|
285
|
+
const result = compile("");
|
|
286
|
+
expect(result.code).toBeDefined();
|
|
287
|
+
});
|
|
288
|
+
test("should handle source with only comments", () => {
|
|
289
|
+
const source = "# This is a comment";
|
|
290
|
+
const result = compile(source);
|
|
291
|
+
expect(result.code).toBeDefined();
|
|
292
|
+
});
|
|
293
|
+
test("should handle source with special characters", () => {
|
|
294
|
+
const source = 'print("Hello! @#$%^&*()")';
|
|
295
|
+
const result = compile(source);
|
|
296
|
+
expect(result.code).toContain("Hello");
|
|
297
|
+
});
|
|
298
|
+
test("should handle unicode characters", () => {
|
|
299
|
+
const source = 'print("こんにちは 世界")';
|
|
300
|
+
const result = compile(source);
|
|
301
|
+
expect(result.code).toContain("こんにちは");
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
describe("Format Combinations", () => {
|
|
305
|
+
const source = 'print("test")';
|
|
306
|
+
test("ESM + inline runtime", () => {
|
|
307
|
+
const result = compile(source, {
|
|
308
|
+
format: "esm",
|
|
309
|
+
runtimeMode: "inline"
|
|
310
|
+
});
|
|
311
|
+
expect(result.code).toContain("function print");
|
|
312
|
+
expect(result.code).not.toContain("import");
|
|
313
|
+
});
|
|
314
|
+
test("CommonJS + inline runtime", () => {
|
|
315
|
+
const result = compile(source, {
|
|
316
|
+
format: "cjs",
|
|
317
|
+
runtimeMode: "inline"
|
|
318
|
+
});
|
|
319
|
+
expect(result.code).toContain("function print");
|
|
320
|
+
expect(result.code).not.toContain("require");
|
|
321
|
+
});
|
|
322
|
+
test("IIFE + CDN runtime", () => {
|
|
323
|
+
const result = compile(source, {
|
|
324
|
+
format: "iife",
|
|
325
|
+
runtimeMode: "cdn"
|
|
326
|
+
});
|
|
327
|
+
expect(result.code).toContain("function");
|
|
328
|
+
});
|
|
329
|
+
test("UMD + external runtime", () => {
|
|
330
|
+
const result = compile(source, {
|
|
331
|
+
format: "umd",
|
|
332
|
+
runtimeMode: "external"
|
|
333
|
+
});
|
|
334
|
+
expect(result.code).toContain("define.amd");
|
|
335
|
+
});
|
|
336
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.test.d.ts","sourceRoot":"","sources":["../../../src/api/__tests__/runtime.test.ts"],"names":[],"mappings":""}
|