jac-client 0.2.3__py3-none-any.whl → 0.2.4__py3-none-any.whl
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.
- jac_client/examples/all-in-one/assets/workers/worker.py +5 -0
- jac_client/tests/conftest.py +281 -0
- jac_client/tests/test_cli.py +755 -0
- jac_client/tests/test_it.py +347 -67
- {jac_client-0.2.3.dist-info → jac_client-0.2.4.dist-info}/METADATA +28 -30
- jac_client-0.2.4.dist-info/RECORD +10 -0
- {jac_client-0.2.3.dist-info → jac_client-0.2.4.dist-info}/WHEEL +2 -1
- jac_client-0.2.4.dist-info/entry_points.txt +4 -0
- jac_client-0.2.4.dist-info/top_level.txt +1 -0
- jac_client/docs/README.md +0 -689
- jac_client/docs/advanced-state.md +0 -1265
- jac_client/docs/asset-serving/intro.md +0 -209
- jac_client/docs/assets/pipe_line-v2.svg +0 -32
- jac_client/docs/assets/pipe_line.png +0 -0
- jac_client/docs/file-system/app.jac.md +0 -121
- jac_client/docs/file-system/backend-frontend.md +0 -217
- jac_client/docs/file-system/intro.md +0 -72
- jac_client/docs/file-system/nested-imports.md +0 -348
- jac_client/docs/guide-example/intro.md +0 -115
- jac_client/docs/guide-example/step-01-setup.md +0 -270
- jac_client/docs/guide-example/step-02-components.md +0 -416
- jac_client/docs/guide-example/step-03-styling.md +0 -478
- jac_client/docs/guide-example/step-04-todo-ui.md +0 -477
- jac_client/docs/guide-example/step-05-local-state.md +0 -530
- jac_client/docs/guide-example/step-06-events.md +0 -749
- jac_client/docs/guide-example/step-07-effects.md +0 -468
- jac_client/docs/guide-example/step-08-walkers.md +0 -534
- jac_client/docs/guide-example/step-09-authentication.md +0 -586
- jac_client/docs/guide-example/step-10-routing.md +0 -539
- jac_client/docs/guide-example/step-11-final.md +0 -963
- jac_client/docs/imports.md +0 -1141
- jac_client/docs/lifecycle-hooks.md +0 -773
- jac_client/docs/routing.md +0 -659
- jac_client/docs/styling/intro.md +0 -249
- jac_client/docs/styling/js-styling.md +0 -367
- jac_client/docs/styling/material-ui.md +0 -341
- jac_client/docs/styling/pure-css.md +0 -299
- jac_client/docs/styling/sass.md +0 -403
- jac_client/docs/styling/styled-components.md +0 -395
- jac_client/docs/styling/tailwind.md +0 -298
- jac_client/examples/all-in-one/.babelrc +0 -9
- jac_client/examples/all-in-one/README.md +0 -16
- jac_client/examples/all-in-one/app.jac +0 -426
- jac_client/examples/all-in-one/assets/burger.png +0 -0
- jac_client/examples/all-in-one/button.jac +0 -7
- jac_client/examples/all-in-one/components/button.jac +0 -7
- jac_client/examples/all-in-one/package.json +0 -29
- jac_client/examples/all-in-one/styles.css +0 -26
- jac_client/examples/all-in-one/vite.config.js +0 -28
- jac_client/examples/asset-serving/css-with-image/.babelrc +0 -9
- jac_client/examples/asset-serving/css-with-image/README.md +0 -91
- jac_client/examples/asset-serving/css-with-image/app.jac +0 -88
- jac_client/examples/asset-serving/css-with-image/assets/burger.png +0 -0
- jac_client/examples/asset-serving/css-with-image/package.json +0 -28
- jac_client/examples/asset-serving/css-with-image/styles.css +0 -26
- jac_client/examples/asset-serving/css-with-image/vite.config.js +0 -28
- jac_client/examples/asset-serving/image-asset/.babelrc +0 -9
- jac_client/examples/asset-serving/image-asset/README.md +0 -119
- jac_client/examples/asset-serving/image-asset/app.jac +0 -55
- jac_client/examples/asset-serving/image-asset/assets/burger.png +0 -0
- jac_client/examples/asset-serving/image-asset/package.json +0 -28
- jac_client/examples/asset-serving/image-asset/styles.css +0 -26
- jac_client/examples/asset-serving/image-asset/vite.config.js +0 -28
- jac_client/examples/asset-serving/import-alias/.babelrc +0 -9
- jac_client/examples/asset-serving/import-alias/README.md +0 -83
- jac_client/examples/asset-serving/import-alias/app.jac +0 -111
- jac_client/examples/asset-serving/import-alias/assets/burger.png +0 -0
- jac_client/examples/asset-serving/import-alias/package.json +0 -28
- jac_client/examples/asset-serving/import-alias/vite.config.js +0 -28
- jac_client/examples/basic/.babelrc +0 -9
- jac_client/examples/basic/README.md +0 -16
- jac_client/examples/basic/app.jac +0 -21
- jac_client/examples/basic/package.json +0 -27
- jac_client/examples/basic/vite.config.js +0 -27
- jac_client/examples/basic-auth/.babelrc +0 -9
- jac_client/examples/basic-auth/README.md +0 -16
- jac_client/examples/basic-auth/app.jac +0 -308
- jac_client/examples/basic-auth/package.json +0 -27
- jac_client/examples/basic-auth/vite.config.js +0 -27
- jac_client/examples/basic-auth-with-router/.babelrc +0 -9
- jac_client/examples/basic-auth-with-router/README.md +0 -60
- jac_client/examples/basic-auth-with-router/app.jac +0 -464
- jac_client/examples/basic-auth-with-router/package.json +0 -28
- jac_client/examples/basic-auth-with-router/vite.config.js +0 -27
- jac_client/examples/basic-full-stack/.babelrc +0 -9
- jac_client/examples/basic-full-stack/README.md +0 -18
- jac_client/examples/basic-full-stack/app.jac +0 -320
- jac_client/examples/basic-full-stack/package.json +0 -28
- jac_client/examples/basic-full-stack/vite.config.js +0 -27
- jac_client/examples/css-styling/js-styling/.babelrc +0 -9
- jac_client/examples/css-styling/js-styling/README.md +0 -183
- jac_client/examples/css-styling/js-styling/app.jac +0 -84
- jac_client/examples/css-styling/js-styling/package.json +0 -28
- jac_client/examples/css-styling/js-styling/styles.js +0 -100
- jac_client/examples/css-styling/js-styling/vite.config.js +0 -27
- jac_client/examples/css-styling/material-ui/.babelrc +0 -9
- jac_client/examples/css-styling/material-ui/README.md +0 -16
- jac_client/examples/css-styling/material-ui/app.jac +0 -122
- jac_client/examples/css-styling/material-ui/package.json +0 -32
- jac_client/examples/css-styling/material-ui/vite.config.js +0 -27
- jac_client/examples/css-styling/pure-css/.babelrc +0 -9
- jac_client/examples/css-styling/pure-css/README.md +0 -16
- jac_client/examples/css-styling/pure-css/app.jac +0 -64
- jac_client/examples/css-styling/pure-css/package.json +0 -28
- jac_client/examples/css-styling/pure-css/styles.css +0 -111
- jac_client/examples/css-styling/pure-css/vite.config.js +0 -27
- jac_client/examples/css-styling/sass-example/.babelrc +0 -9
- jac_client/examples/css-styling/sass-example/README.md +0 -16
- jac_client/examples/css-styling/sass-example/app.jac +0 -64
- jac_client/examples/css-styling/sass-example/package.json +0 -29
- jac_client/examples/css-styling/sass-example/styles.scss +0 -153
- jac_client/examples/css-styling/sass-example/vite.config.js +0 -27
- jac_client/examples/css-styling/styled-components/.babelrc +0 -9
- jac_client/examples/css-styling/styled-components/README.md +0 -16
- jac_client/examples/css-styling/styled-components/app.jac +0 -71
- jac_client/examples/css-styling/styled-components/package.json +0 -29
- jac_client/examples/css-styling/styled-components/styled.js +0 -90
- jac_client/examples/css-styling/styled-components/vite.config.js +0 -27
- jac_client/examples/css-styling/tailwind-example/.babelrc +0 -9
- jac_client/examples/css-styling/tailwind-example/README.md +0 -16
- jac_client/examples/css-styling/tailwind-example/app.jac +0 -63
- jac_client/examples/css-styling/tailwind-example/global.css +0 -1
- jac_client/examples/css-styling/tailwind-example/package.json +0 -30
- jac_client/examples/css-styling/tailwind-example/vite.config.js +0 -29
- jac_client/examples/full-stack-with-auth/.babelrc +0 -9
- jac_client/examples/full-stack-with-auth/README.md +0 -16
- jac_client/examples/full-stack-with-auth/app.jac +0 -722
- jac_client/examples/full-stack-with-auth/package.json +0 -28
- jac_client/examples/full-stack-with-auth/vite.config.js +0 -29
- jac_client/examples/little-x/app.jac +0 -724
- jac_client/examples/little-x/package.json +0 -23
- jac_client/examples/little-x/submit-button.jac +0 -8
- jac_client/examples/nested-folders/nested-advance/.babelrc +0 -9
- jac_client/examples/nested-folders/nested-advance/ButtonRoot.jac +0 -11
- jac_client/examples/nested-folders/nested-advance/README.md +0 -77
- jac_client/examples/nested-folders/nested-advance/app.jac +0 -35
- jac_client/examples/nested-folders/nested-advance/level1/ButtonSecondL.jac +0 -19
- jac_client/examples/nested-folders/nested-advance/level1/Card.jac +0 -43
- jac_client/examples/nested-folders/nested-advance/level1/level2/ButtonThirdL.jac +0 -25
- jac_client/examples/nested-folders/nested-advance/package.json +0 -29
- jac_client/examples/nested-folders/nested-advance/vite.config.js +0 -28
- jac_client/examples/nested-folders/nested-basic/.babelrc +0 -9
- jac_client/examples/nested-folders/nested-basic/README.md +0 -183
- jac_client/examples/nested-folders/nested-basic/app.jac +0 -13
- jac_client/examples/nested-folders/nested-basic/app.js +0 -7
- jac_client/examples/nested-folders/nested-basic/button.jac +0 -7
- jac_client/examples/nested-folders/nested-basic/components/button.jac +0 -7
- jac_client/examples/nested-folders/nested-basic/package.json +0 -28
- jac_client/examples/nested-folders/nested-basic/vite.config.js +0 -27
- jac_client/examples/with-router/.babelrc +0 -9
- jac_client/examples/with-router/README.md +0 -17
- jac_client/examples/with-router/app.jac +0 -323
- jac_client/examples/with-router/package.json +0 -28
- jac_client/examples/with-router/vite.config.js +0 -27
- jac_client/plugin/cli.py +0 -244
- jac_client/plugin/client.py +0 -152
- jac_client/plugin/client_runtime.jac +0 -234
- jac_client/plugin/vite_client_bundle.py +0 -503
- jac_client/tests/fixtures/basic-app/app.jac +0 -23
- jac_client/tests/fixtures/cl_file/app.cl.jac +0 -48
- jac_client/tests/fixtures/cl_file/app.jac +0 -15
- jac_client/tests/fixtures/client_app_with_antd/app.jac +0 -34
- jac_client/tests/fixtures/js_import/app.jac +0 -34
- jac_client/tests/fixtures/js_import/utils.js +0 -21
- jac_client/tests/fixtures/package-lock.json +0 -329
- jac_client/tests/fixtures/package.json +0 -11
- jac_client/tests/fixtures/relative_import/app.jac +0 -11
- jac_client/tests/fixtures/relative_import/button.jac +0 -7
- jac_client/tests/fixtures/spawn_test/app.jac +0 -129
- jac_client/tests/fixtures/test_fragments_spread/app.jac +0 -67
- jac_client/tests/test_asset_examples.py +0 -322
- jac_client/tests/test_cl.py +0 -530
- jac_client/tests/test_create_jac_app.py +0 -131
- jac_client/tests/test_nested_file.py +0 -374
- jac_client-0.2.3.dist-info/RECORD +0 -171
- jac_client-0.2.3.dist-info/entry_points.txt +0 -4
|
@@ -0,0 +1,755 @@
|
|
|
1
|
+
"""Test create-jac-app command."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import tempfile
|
|
5
|
+
import tomllib
|
|
6
|
+
from subprocess import PIPE, Popen, run
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def test_create_jac_app() -> None:
|
|
10
|
+
"""Test jac create --cl command."""
|
|
11
|
+
test_project_name = "test-jac-app"
|
|
12
|
+
|
|
13
|
+
# Create a temporary directory for testing
|
|
14
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
15
|
+
original_cwd = os.getcwd()
|
|
16
|
+
try:
|
|
17
|
+
# Change to temp directory
|
|
18
|
+
os.chdir(temp_dir)
|
|
19
|
+
|
|
20
|
+
# Run jac create --cl command
|
|
21
|
+
process = Popen(
|
|
22
|
+
["jac", "create", "--cl", test_project_name],
|
|
23
|
+
stdin=PIPE,
|
|
24
|
+
stdout=PIPE,
|
|
25
|
+
stderr=PIPE,
|
|
26
|
+
text=True,
|
|
27
|
+
)
|
|
28
|
+
stdout, stderr = process.communicate()
|
|
29
|
+
result_code = process.returncode
|
|
30
|
+
|
|
31
|
+
# Check that command succeeded
|
|
32
|
+
assert result_code == 0
|
|
33
|
+
assert f"Project '{test_project_name}' created successfully!" in stdout
|
|
34
|
+
|
|
35
|
+
# Verify project directory was created
|
|
36
|
+
project_path = os.path.join(temp_dir, test_project_name)
|
|
37
|
+
assert os.path.exists(project_path)
|
|
38
|
+
assert os.path.isdir(project_path)
|
|
39
|
+
|
|
40
|
+
# Verify src/app.jac file was created
|
|
41
|
+
app_jac_path = os.path.join(project_path, "src", "app.jac")
|
|
42
|
+
assert os.path.exists(app_jac_path)
|
|
43
|
+
|
|
44
|
+
with open(app_jac_path) as f:
|
|
45
|
+
app_jac_content = f.read()
|
|
46
|
+
|
|
47
|
+
assert "def:pub app()" in app_jac_content
|
|
48
|
+
|
|
49
|
+
# Verify README.md was created
|
|
50
|
+
readme_path = os.path.join(project_path, "README.md")
|
|
51
|
+
assert os.path.exists(readme_path)
|
|
52
|
+
|
|
53
|
+
with open(readme_path) as f:
|
|
54
|
+
readme_content = f.read()
|
|
55
|
+
|
|
56
|
+
assert f"# {test_project_name}" in readme_content
|
|
57
|
+
assert "jac serve src/app.jac" in readme_content
|
|
58
|
+
|
|
59
|
+
# Verify jac.toml was created
|
|
60
|
+
jac_toml_path = os.path.join(project_path, "jac.toml")
|
|
61
|
+
assert os.path.exists(jac_toml_path)
|
|
62
|
+
|
|
63
|
+
with open(jac_toml_path, "rb") as f:
|
|
64
|
+
config_data = tomllib.load(f)
|
|
65
|
+
|
|
66
|
+
assert config_data["project"]["name"] == test_project_name
|
|
67
|
+
|
|
68
|
+
# Verify .gitignore was created with correct content
|
|
69
|
+
gitignore_path = os.path.join(project_path, ".gitignore")
|
|
70
|
+
assert os.path.exists(gitignore_path)
|
|
71
|
+
|
|
72
|
+
with open(gitignore_path) as f:
|
|
73
|
+
gitignore_content = f.read()
|
|
74
|
+
|
|
75
|
+
assert "node_modules" in gitignore_content
|
|
76
|
+
|
|
77
|
+
# Verify src/components directory exists
|
|
78
|
+
components_dir = os.path.join(project_path, "src", "components")
|
|
79
|
+
assert os.path.exists(components_dir)
|
|
80
|
+
|
|
81
|
+
# Verify default packages installation (package.json should be generated)
|
|
82
|
+
package_json_path = os.path.join(
|
|
83
|
+
project_path, ".client-build", ".jac-client.configs", "package.json"
|
|
84
|
+
)
|
|
85
|
+
# Note: packages may or may not be installed depending on npm availability
|
|
86
|
+
# but package.json should be generated with default packages
|
|
87
|
+
if os.path.exists(package_json_path):
|
|
88
|
+
import json
|
|
89
|
+
|
|
90
|
+
with open(package_json_path) as f:
|
|
91
|
+
package_data = json.load(f)
|
|
92
|
+
|
|
93
|
+
# Verify default dependencies are in package.json
|
|
94
|
+
assert "react" in package_data.get("dependencies", {})
|
|
95
|
+
assert "react-dom" in package_data.get("dependencies", {})
|
|
96
|
+
assert "vite" in package_data.get("devDependencies", {})
|
|
97
|
+
|
|
98
|
+
finally:
|
|
99
|
+
# Return to original directory
|
|
100
|
+
os.chdir(original_cwd)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def test_create_jac_app_invalid_name() -> None:
|
|
104
|
+
"""Test jac create --cl command with invalid project name."""
|
|
105
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
106
|
+
original_cwd = os.getcwd()
|
|
107
|
+
try:
|
|
108
|
+
os.chdir(temp_dir)
|
|
109
|
+
|
|
110
|
+
# Test with invalid name containing spaces
|
|
111
|
+
result = run(
|
|
112
|
+
["jac", "create", "--cl", "invalid name with spaces"],
|
|
113
|
+
capture_output=True,
|
|
114
|
+
text=True,
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
# Should fail with non-zero exit code
|
|
118
|
+
assert result.returncode != 0
|
|
119
|
+
assert (
|
|
120
|
+
"Project name must contain only letters, numbers, hyphens, and underscores"
|
|
121
|
+
in result.stderr
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
finally:
|
|
125
|
+
os.chdir(original_cwd)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def test_create_jac_app_existing_directory() -> None:
|
|
129
|
+
"""Test jac create --cl command when directory already exists."""
|
|
130
|
+
test_project_name = "existing-test-app"
|
|
131
|
+
|
|
132
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
133
|
+
original_cwd = os.getcwd()
|
|
134
|
+
try:
|
|
135
|
+
os.chdir(temp_dir)
|
|
136
|
+
|
|
137
|
+
# Create the directory first
|
|
138
|
+
os.makedirs(test_project_name)
|
|
139
|
+
|
|
140
|
+
# Try to create app with same name
|
|
141
|
+
process = Popen(
|
|
142
|
+
["jac", "create", "--cl", test_project_name],
|
|
143
|
+
stdin=PIPE,
|
|
144
|
+
stdout=PIPE,
|
|
145
|
+
stderr=PIPE,
|
|
146
|
+
text=True,
|
|
147
|
+
)
|
|
148
|
+
stdout, stderr = process.communicate()
|
|
149
|
+
result_code = process.returncode
|
|
150
|
+
|
|
151
|
+
# Should fail with non-zero exit code
|
|
152
|
+
assert result_code != 0
|
|
153
|
+
assert f"Directory '{test_project_name}' already exists" in stderr
|
|
154
|
+
|
|
155
|
+
finally:
|
|
156
|
+
os.chdir(original_cwd)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def test_create_jac_app_with_typescript() -> None:
|
|
160
|
+
"""Test jac create --cl command with TypeScript support (enabled by default)."""
|
|
161
|
+
test_project_name = "test-jac-app-ts"
|
|
162
|
+
|
|
163
|
+
# Create a temporary directory for testing
|
|
164
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
165
|
+
original_cwd = os.getcwd()
|
|
166
|
+
try:
|
|
167
|
+
# Change to temp directory
|
|
168
|
+
os.chdir(temp_dir)
|
|
169
|
+
|
|
170
|
+
# Run jac create --cl command (TypeScript is enabled by default)
|
|
171
|
+
process = Popen(
|
|
172
|
+
["jac", "create", "--cl", test_project_name],
|
|
173
|
+
stdin=PIPE,
|
|
174
|
+
stdout=PIPE,
|
|
175
|
+
stderr=PIPE,
|
|
176
|
+
text=True,
|
|
177
|
+
)
|
|
178
|
+
stdout, stderr = process.communicate()
|
|
179
|
+
result_code = process.returncode
|
|
180
|
+
|
|
181
|
+
# Check that command succeeded
|
|
182
|
+
assert result_code == 0
|
|
183
|
+
assert f"Project '{test_project_name}' created successfully!" in stdout
|
|
184
|
+
|
|
185
|
+
# Verify project directory was created
|
|
186
|
+
project_path = os.path.join(temp_dir, test_project_name)
|
|
187
|
+
assert os.path.exists(project_path)
|
|
188
|
+
assert os.path.isdir(project_path)
|
|
189
|
+
|
|
190
|
+
# Verify jac.toml was created
|
|
191
|
+
jac_toml_path = os.path.join(project_path, "jac.toml")
|
|
192
|
+
assert os.path.exists(jac_toml_path)
|
|
193
|
+
|
|
194
|
+
with open(jac_toml_path, "rb") as f:
|
|
195
|
+
config_data = tomllib.load(f)
|
|
196
|
+
|
|
197
|
+
assert config_data["project"]["name"] == test_project_name
|
|
198
|
+
|
|
199
|
+
# Verify src/components directory and Button.tsx were created
|
|
200
|
+
components_dir = os.path.join(project_path, "src", "components")
|
|
201
|
+
assert os.path.exists(components_dir)
|
|
202
|
+
assert os.path.isdir(components_dir)
|
|
203
|
+
|
|
204
|
+
button_tsx_path = os.path.join(components_dir, "Button.tsx")
|
|
205
|
+
assert os.path.exists(button_tsx_path)
|
|
206
|
+
|
|
207
|
+
with open(button_tsx_path) as f:
|
|
208
|
+
button_content = f.read()
|
|
209
|
+
|
|
210
|
+
assert "interface ButtonProps" in button_content
|
|
211
|
+
assert "export const Button" in button_content
|
|
212
|
+
|
|
213
|
+
# Verify src/app.jac includes TypeScript import
|
|
214
|
+
app_jac_path = os.path.join(project_path, "src", "app.jac")
|
|
215
|
+
assert os.path.exists(app_jac_path)
|
|
216
|
+
|
|
217
|
+
with open(app_jac_path) as f:
|
|
218
|
+
app_jac_content = f.read()
|
|
219
|
+
|
|
220
|
+
assert (
|
|
221
|
+
'cl import from ".components/Button.tsx" { Button }' in app_jac_content
|
|
222
|
+
)
|
|
223
|
+
assert "<Button" in app_jac_content
|
|
224
|
+
|
|
225
|
+
# Verify README.md includes TypeScript information
|
|
226
|
+
readme_path = os.path.join(project_path, "README.md")
|
|
227
|
+
assert os.path.exists(readme_path)
|
|
228
|
+
|
|
229
|
+
with open(readme_path) as f:
|
|
230
|
+
readme_content = f.read()
|
|
231
|
+
|
|
232
|
+
assert "TypeScript Support" in readme_content
|
|
233
|
+
assert "components/Button.tsx" in readme_content
|
|
234
|
+
|
|
235
|
+
# Verify default packages installation (package.json should be generated)
|
|
236
|
+
package_json_path = os.path.join(
|
|
237
|
+
project_path, ".client-build", ".jac-client.configs", "package.json"
|
|
238
|
+
)
|
|
239
|
+
# Note: packages may or may not be installed depending on npm availability
|
|
240
|
+
# but package.json should be generated with default packages
|
|
241
|
+
if os.path.exists(package_json_path):
|
|
242
|
+
import json
|
|
243
|
+
|
|
244
|
+
with open(package_json_path) as f:
|
|
245
|
+
package_data = json.load(f)
|
|
246
|
+
|
|
247
|
+
# Verify default dependencies are in package.json
|
|
248
|
+
assert "react" in package_data.get("dependencies", {})
|
|
249
|
+
assert "react-dom" in package_data.get("dependencies", {})
|
|
250
|
+
assert "vite" in package_data.get("devDependencies", {})
|
|
251
|
+
assert "typescript" in package_data.get("devDependencies", {})
|
|
252
|
+
|
|
253
|
+
finally:
|
|
254
|
+
# Return to original directory
|
|
255
|
+
os.chdir(original_cwd)
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
def test_create_jac_app_with_skip_flag() -> None:
|
|
259
|
+
"""Test jac create --cl --skip command skips package installation."""
|
|
260
|
+
test_project_name = "test-jac-app-skip"
|
|
261
|
+
|
|
262
|
+
# Create a temporary directory for testing
|
|
263
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
264
|
+
original_cwd = os.getcwd()
|
|
265
|
+
try:
|
|
266
|
+
# Change to temp directory
|
|
267
|
+
os.chdir(temp_dir)
|
|
268
|
+
|
|
269
|
+
# Run jac create --cl --skip command
|
|
270
|
+
process = Popen(
|
|
271
|
+
["jac", "create", "--cl", "--skip", test_project_name],
|
|
272
|
+
stdin=PIPE,
|
|
273
|
+
stdout=PIPE,
|
|
274
|
+
stderr=PIPE,
|
|
275
|
+
text=True,
|
|
276
|
+
)
|
|
277
|
+
stdout, stderr = process.communicate()
|
|
278
|
+
result_code = process.returncode
|
|
279
|
+
|
|
280
|
+
# Check that command succeeded
|
|
281
|
+
assert result_code == 0
|
|
282
|
+
assert f"Project '{test_project_name}' created successfully!" in stdout
|
|
283
|
+
|
|
284
|
+
# Verify project directory was created
|
|
285
|
+
project_path = os.path.join(temp_dir, test_project_name)
|
|
286
|
+
assert os.path.exists(project_path)
|
|
287
|
+
assert os.path.isdir(project_path)
|
|
288
|
+
|
|
289
|
+
# Verify that "Installing default packages" message is NOT in output
|
|
290
|
+
assert "Installing default packages" not in stdout
|
|
291
|
+
assert "Default packages installed successfully" not in stdout
|
|
292
|
+
|
|
293
|
+
# Verify jac.toml was created
|
|
294
|
+
jac_toml_path = os.path.join(project_path, "jac.toml")
|
|
295
|
+
assert os.path.exists(jac_toml_path)
|
|
296
|
+
|
|
297
|
+
finally:
|
|
298
|
+
# Return to original directory
|
|
299
|
+
os.chdir(original_cwd)
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
def test_create_jac_app_installs_default_packages() -> None:
|
|
303
|
+
"""Test jac create --cl command attempts to install default packages."""
|
|
304
|
+
test_project_name = "test-jac-app-install"
|
|
305
|
+
|
|
306
|
+
# Create a temporary directory for testing
|
|
307
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
308
|
+
original_cwd = os.getcwd()
|
|
309
|
+
try:
|
|
310
|
+
# Change to temp directory
|
|
311
|
+
os.chdir(temp_dir)
|
|
312
|
+
|
|
313
|
+
# Run jac create --cl command
|
|
314
|
+
process = Popen(
|
|
315
|
+
["jac", "create", "--cl", test_project_name],
|
|
316
|
+
stdin=PIPE,
|
|
317
|
+
stdout=PIPE,
|
|
318
|
+
stderr=PIPE,
|
|
319
|
+
text=True,
|
|
320
|
+
)
|
|
321
|
+
stdout, stderr = process.communicate()
|
|
322
|
+
result_code = process.returncode
|
|
323
|
+
|
|
324
|
+
# Check that command succeeded
|
|
325
|
+
assert result_code == 0
|
|
326
|
+
assert f"Project '{test_project_name}' created successfully!" in stdout
|
|
327
|
+
|
|
328
|
+
# Verify project directory was created
|
|
329
|
+
project_path = os.path.join(temp_dir, test_project_name)
|
|
330
|
+
assert os.path.exists(project_path)
|
|
331
|
+
|
|
332
|
+
# Verify that installation was attempted (message should be in output)
|
|
333
|
+
assert "Installing default packages" in stdout
|
|
334
|
+
|
|
335
|
+
# Verify package.json was generated (even if npm install failed)
|
|
336
|
+
package_json_path = os.path.join(
|
|
337
|
+
project_path, ".client-build", ".jac-client.configs", "package.json"
|
|
338
|
+
)
|
|
339
|
+
# package.json should be generated with default packages
|
|
340
|
+
if os.path.exists(package_json_path):
|
|
341
|
+
import json
|
|
342
|
+
|
|
343
|
+
with open(package_json_path) as f:
|
|
344
|
+
package_data = json.load(f)
|
|
345
|
+
|
|
346
|
+
# Verify default dependencies are in package.json
|
|
347
|
+
deps = package_data.get("dependencies", {})
|
|
348
|
+
dev_deps = package_data.get("devDependencies", {})
|
|
349
|
+
|
|
350
|
+
assert "react" in deps
|
|
351
|
+
assert "react-dom" in deps
|
|
352
|
+
assert "react-router-dom" in deps
|
|
353
|
+
assert "vite" in dev_deps
|
|
354
|
+
assert "@babel/core" in dev_deps
|
|
355
|
+
assert "typescript" in dev_deps
|
|
356
|
+
assert "@types/react" in dev_deps
|
|
357
|
+
|
|
358
|
+
finally:
|
|
359
|
+
# Return to original directory
|
|
360
|
+
os.chdir(original_cwd)
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
def test_generate_client_config() -> None:
|
|
364
|
+
"""Test that generate_client_config command no longer exists (use jac init instead)."""
|
|
365
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
366
|
+
original_cwd = os.getcwd()
|
|
367
|
+
try:
|
|
368
|
+
os.chdir(temp_dir)
|
|
369
|
+
|
|
370
|
+
# Run generate_client_config command - should not exist
|
|
371
|
+
result = run(
|
|
372
|
+
["jac", "generate_client_config"],
|
|
373
|
+
capture_output=True,
|
|
374
|
+
text=True,
|
|
375
|
+
)
|
|
376
|
+
|
|
377
|
+
# Command should not exist anymore
|
|
378
|
+
assert result.returncode != 0
|
|
379
|
+
|
|
380
|
+
finally:
|
|
381
|
+
os.chdir(original_cwd)
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
def test_generate_client_config_existing_file() -> None:
|
|
385
|
+
"""Test that generate_client_config command no longer exists."""
|
|
386
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
387
|
+
original_cwd = os.getcwd()
|
|
388
|
+
try:
|
|
389
|
+
os.chdir(temp_dir)
|
|
390
|
+
|
|
391
|
+
# Run generate_client_config command - should not exist
|
|
392
|
+
result = run(
|
|
393
|
+
["jac", "generate_client_config"],
|
|
394
|
+
capture_output=True,
|
|
395
|
+
text=True,
|
|
396
|
+
)
|
|
397
|
+
|
|
398
|
+
# Command should not exist anymore
|
|
399
|
+
assert result.returncode != 0
|
|
400
|
+
|
|
401
|
+
finally:
|
|
402
|
+
os.chdir(original_cwd)
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
def _create_jac_toml(temp_dir: str, deps: str = "", dev_deps: str = "") -> str:
|
|
406
|
+
"""Create a minimal jac.toml file for testing.
|
|
407
|
+
|
|
408
|
+
Note: These CLI tests run jac commands as subprocesses and include npm install.
|
|
409
|
+
For faster tests, consider using unit tests with mocked PackageInstaller.
|
|
410
|
+
"""
|
|
411
|
+
deps_section = f"\n{deps}" if deps else ""
|
|
412
|
+
dev_deps_section = f"\n{dev_deps}" if dev_deps else ""
|
|
413
|
+
|
|
414
|
+
toml_content = f"""[project]
|
|
415
|
+
name = "test-project"
|
|
416
|
+
version = "1.0.0"
|
|
417
|
+
description = "Test project"
|
|
418
|
+
entry-point = "app.jac"
|
|
419
|
+
|
|
420
|
+
[dependencies.npm]{deps_section}
|
|
421
|
+
|
|
422
|
+
[dev-dependencies.npm]{dev_deps_section}
|
|
423
|
+
"""
|
|
424
|
+
config_path = os.path.join(temp_dir, "jac.toml")
|
|
425
|
+
with open(config_path, "w") as f:
|
|
426
|
+
f.write(toml_content)
|
|
427
|
+
return config_path
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
def test_install_without_cl_flag() -> None:
|
|
431
|
+
"""Test add command without --cl flag should fail when no jac.toml exists."""
|
|
432
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
433
|
+
original_cwd = os.getcwd()
|
|
434
|
+
try:
|
|
435
|
+
os.chdir(temp_dir)
|
|
436
|
+
|
|
437
|
+
# Run add command without --cl flag and without jac.toml
|
|
438
|
+
result = run(
|
|
439
|
+
["jac", "add", "lodash"],
|
|
440
|
+
capture_output=True,
|
|
441
|
+
text=True,
|
|
442
|
+
)
|
|
443
|
+
|
|
444
|
+
# Should fail with non-zero exit code because no jac.toml
|
|
445
|
+
assert result.returncode != 0
|
|
446
|
+
assert "No jac.toml found" in result.stderr
|
|
447
|
+
|
|
448
|
+
finally:
|
|
449
|
+
os.chdir(original_cwd)
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
def test_install_all_packages() -> None:
|
|
453
|
+
"""Test add --cl command installs all packages from jac.toml."""
|
|
454
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
455
|
+
original_cwd = os.getcwd()
|
|
456
|
+
try:
|
|
457
|
+
os.chdir(temp_dir)
|
|
458
|
+
|
|
459
|
+
# Create jac.toml with some dependencies
|
|
460
|
+
_create_jac_toml(temp_dir, deps='lodash = "^4.17.21"')
|
|
461
|
+
|
|
462
|
+
# Run add --cl command without package name
|
|
463
|
+
result = run(
|
|
464
|
+
["jac", "add", "--cl"],
|
|
465
|
+
capture_output=True,
|
|
466
|
+
text=True,
|
|
467
|
+
)
|
|
468
|
+
|
|
469
|
+
# Should succeed
|
|
470
|
+
assert result.returncode == 0
|
|
471
|
+
assert "Installing all npm packages" in result.stdout
|
|
472
|
+
assert "Installed all npm packages successfully" in result.stdout
|
|
473
|
+
|
|
474
|
+
finally:
|
|
475
|
+
os.chdir(original_cwd)
|
|
476
|
+
|
|
477
|
+
|
|
478
|
+
def test_install_package_to_dependencies() -> None:
|
|
479
|
+
"""Test add --cl command adds package to dependencies."""
|
|
480
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
481
|
+
original_cwd = os.getcwd()
|
|
482
|
+
try:
|
|
483
|
+
os.chdir(temp_dir)
|
|
484
|
+
|
|
485
|
+
# Create jac.toml
|
|
486
|
+
config_path = _create_jac_toml(temp_dir)
|
|
487
|
+
|
|
488
|
+
# Run add --cl command with package name
|
|
489
|
+
result = run(
|
|
490
|
+
["jac", "add", "--cl", "lodash"],
|
|
491
|
+
capture_output=True,
|
|
492
|
+
text=True,
|
|
493
|
+
)
|
|
494
|
+
|
|
495
|
+
# Should succeed
|
|
496
|
+
assert result.returncode == 0
|
|
497
|
+
assert "Adding lodash (npm)" in result.stdout
|
|
498
|
+
assert "Added 1 package(s) to [dependencies.npm]" in result.stdout
|
|
499
|
+
|
|
500
|
+
# Verify package was added to jac.toml
|
|
501
|
+
with open(config_path, "rb") as f:
|
|
502
|
+
updated_config = tomllib.load(f)
|
|
503
|
+
|
|
504
|
+
assert "lodash" in updated_config["dependencies"]["npm"]
|
|
505
|
+
|
|
506
|
+
finally:
|
|
507
|
+
os.chdir(original_cwd)
|
|
508
|
+
|
|
509
|
+
|
|
510
|
+
def test_install_package_with_version() -> None:
|
|
511
|
+
"""Test add --cl command with specific version."""
|
|
512
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
513
|
+
original_cwd = os.getcwd()
|
|
514
|
+
try:
|
|
515
|
+
os.chdir(temp_dir)
|
|
516
|
+
|
|
517
|
+
# Create jac.toml
|
|
518
|
+
config_path = _create_jac_toml(temp_dir)
|
|
519
|
+
|
|
520
|
+
# Run add --cl command with package and version
|
|
521
|
+
result = run(
|
|
522
|
+
["jac", "add", "--cl", "lodash@^4.17.21"],
|
|
523
|
+
capture_output=True,
|
|
524
|
+
text=True,
|
|
525
|
+
)
|
|
526
|
+
|
|
527
|
+
# Should succeed
|
|
528
|
+
assert result.returncode == 0
|
|
529
|
+
assert "Adding lodash (npm)" in result.stdout
|
|
530
|
+
assert "Added 1 package(s) to [dependencies.npm]" in result.stdout
|
|
531
|
+
|
|
532
|
+
# Verify package was added with correct version
|
|
533
|
+
with open(config_path, "rb") as f:
|
|
534
|
+
updated_config = tomllib.load(f)
|
|
535
|
+
|
|
536
|
+
assert updated_config["dependencies"]["npm"]["lodash"] == "^4.17.21"
|
|
537
|
+
|
|
538
|
+
finally:
|
|
539
|
+
os.chdir(original_cwd)
|
|
540
|
+
|
|
541
|
+
|
|
542
|
+
def test_install_package_to_devdependencies() -> None:
|
|
543
|
+
"""Test add --cl -d command adds package to dev-dependencies."""
|
|
544
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
545
|
+
original_cwd = os.getcwd()
|
|
546
|
+
try:
|
|
547
|
+
os.chdir(temp_dir)
|
|
548
|
+
|
|
549
|
+
# Create jac.toml
|
|
550
|
+
config_path = _create_jac_toml(temp_dir)
|
|
551
|
+
|
|
552
|
+
# Run add --cl -d command
|
|
553
|
+
run(
|
|
554
|
+
["jac", "add", "--cl", "-d", "@types/react"],
|
|
555
|
+
capture_output=True,
|
|
556
|
+
text=True,
|
|
557
|
+
)
|
|
558
|
+
|
|
559
|
+
# Verify package was added to dev-dependencies in jac.toml
|
|
560
|
+
with open(config_path, "rb") as f:
|
|
561
|
+
updated_config = tomllib.load(f)
|
|
562
|
+
|
|
563
|
+
npm_deps = updated_config["dependencies"]["npm"]
|
|
564
|
+
assert "@types/react" in npm_deps.get("dev", {})
|
|
565
|
+
# Check it's not in regular deps (excluding the "dev" key)
|
|
566
|
+
regular_deps = {k: v for k, v in npm_deps.items() if k != "dev"}
|
|
567
|
+
assert "@types/react" not in regular_deps
|
|
568
|
+
|
|
569
|
+
finally:
|
|
570
|
+
os.chdir(original_cwd)
|
|
571
|
+
|
|
572
|
+
|
|
573
|
+
def test_install_without_config_json() -> None:
|
|
574
|
+
"""Test add --cl command when jac.toml doesn't exist."""
|
|
575
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
576
|
+
original_cwd = os.getcwd()
|
|
577
|
+
try:
|
|
578
|
+
os.chdir(temp_dir)
|
|
579
|
+
|
|
580
|
+
# Run add --cl command without jac.toml
|
|
581
|
+
result = run(
|
|
582
|
+
["jac", "add", "--cl", "lodash"],
|
|
583
|
+
capture_output=True,
|
|
584
|
+
text=True,
|
|
585
|
+
)
|
|
586
|
+
|
|
587
|
+
# Should fail with non-zero exit code
|
|
588
|
+
assert result.returncode != 0
|
|
589
|
+
assert "No jac.toml found" in result.stderr
|
|
590
|
+
|
|
591
|
+
finally:
|
|
592
|
+
os.chdir(original_cwd)
|
|
593
|
+
|
|
594
|
+
|
|
595
|
+
def test_uninstall_without_cl_flag() -> None:
|
|
596
|
+
"""Test remove command without --cl flag should fail when no jac.toml exists."""
|
|
597
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
598
|
+
original_cwd = os.getcwd()
|
|
599
|
+
try:
|
|
600
|
+
os.chdir(temp_dir)
|
|
601
|
+
|
|
602
|
+
# Run remove command without --cl flag and without jac.toml
|
|
603
|
+
result = run(
|
|
604
|
+
["jac", "remove", "lodash"],
|
|
605
|
+
capture_output=True,
|
|
606
|
+
text=True,
|
|
607
|
+
)
|
|
608
|
+
|
|
609
|
+
# Should fail with non-zero exit code because no jac.toml
|
|
610
|
+
assert result.returncode != 0
|
|
611
|
+
assert "No jac.toml found" in result.stderr
|
|
612
|
+
|
|
613
|
+
finally:
|
|
614
|
+
os.chdir(original_cwd)
|
|
615
|
+
|
|
616
|
+
|
|
617
|
+
def test_uninstall_without_package_name() -> None:
|
|
618
|
+
"""Test remove --cl command without package name should fail."""
|
|
619
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
620
|
+
original_cwd = os.getcwd()
|
|
621
|
+
try:
|
|
622
|
+
os.chdir(temp_dir)
|
|
623
|
+
|
|
624
|
+
# Create jac.toml
|
|
625
|
+
_create_jac_toml(temp_dir)
|
|
626
|
+
|
|
627
|
+
# Run remove --cl command without package name
|
|
628
|
+
result = run(
|
|
629
|
+
["jac", "remove", "--cl"],
|
|
630
|
+
capture_output=True,
|
|
631
|
+
text=True,
|
|
632
|
+
)
|
|
633
|
+
|
|
634
|
+
# Should fail with non-zero exit code
|
|
635
|
+
assert result.returncode != 0
|
|
636
|
+
assert "No packages specified" in result.stderr
|
|
637
|
+
|
|
638
|
+
finally:
|
|
639
|
+
os.chdir(original_cwd)
|
|
640
|
+
|
|
641
|
+
|
|
642
|
+
def test_uninstall_package_from_dependencies() -> None:
|
|
643
|
+
"""Test remove --cl command removes package from dependencies."""
|
|
644
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
645
|
+
original_cwd = os.getcwd()
|
|
646
|
+
try:
|
|
647
|
+
os.chdir(temp_dir)
|
|
648
|
+
|
|
649
|
+
# Create jac.toml with a package
|
|
650
|
+
config_path = _create_jac_toml(temp_dir, deps='lodash = "^4.17.21"')
|
|
651
|
+
|
|
652
|
+
# Run remove --cl command
|
|
653
|
+
result = run(
|
|
654
|
+
["jac", "remove", "--cl", "lodash"],
|
|
655
|
+
capture_output=True,
|
|
656
|
+
text=True,
|
|
657
|
+
)
|
|
658
|
+
|
|
659
|
+
# Should succeed
|
|
660
|
+
assert result.returncode == 0
|
|
661
|
+
assert "Removing lodash (npm)" in result.stdout
|
|
662
|
+
assert "Removed 1 package(s)" in result.stdout
|
|
663
|
+
|
|
664
|
+
# Verify package was removed from jac.toml
|
|
665
|
+
with open(config_path, "rb") as f:
|
|
666
|
+
updated_config = tomllib.load(f)
|
|
667
|
+
|
|
668
|
+
npm_deps = updated_config.get("dependencies", {}).get("npm", {})
|
|
669
|
+
regular_deps = {k: v for k, v in npm_deps.items() if k != "dev"}
|
|
670
|
+
assert "lodash" not in regular_deps
|
|
671
|
+
|
|
672
|
+
finally:
|
|
673
|
+
os.chdir(original_cwd)
|
|
674
|
+
|
|
675
|
+
|
|
676
|
+
def test_uninstall_package_from_devdependencies() -> None:
|
|
677
|
+
"""Test remove --cl -d command removes package from dev-dependencies."""
|
|
678
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
679
|
+
original_cwd = os.getcwd()
|
|
680
|
+
try:
|
|
681
|
+
os.chdir(temp_dir)
|
|
682
|
+
|
|
683
|
+
# Create jac.toml with a dev-dependency
|
|
684
|
+
config_path = _create_jac_toml(
|
|
685
|
+
temp_dir, dev_deps='"@types/react" = "^18.0.0"'
|
|
686
|
+
)
|
|
687
|
+
|
|
688
|
+
# Run remove --cl -d command
|
|
689
|
+
result = run(
|
|
690
|
+
["jac", "remove", "--cl", "-d", "@types/react"],
|
|
691
|
+
capture_output=True,
|
|
692
|
+
text=True,
|
|
693
|
+
)
|
|
694
|
+
|
|
695
|
+
# Should succeed
|
|
696
|
+
assert result.returncode == 0
|
|
697
|
+
assert "Removing @types/react (npm)" in result.stdout
|
|
698
|
+
assert "Removed 1 package(s)" in result.stdout
|
|
699
|
+
|
|
700
|
+
# Verify package was removed from jac.toml
|
|
701
|
+
with open(config_path, "rb") as f:
|
|
702
|
+
updated_config = tomllib.load(f)
|
|
703
|
+
|
|
704
|
+
npm_deps = updated_config.get("dependencies", {}).get("npm", {})
|
|
705
|
+
assert "@types/react" not in npm_deps.get("dev", {})
|
|
706
|
+
|
|
707
|
+
finally:
|
|
708
|
+
os.chdir(original_cwd)
|
|
709
|
+
|
|
710
|
+
|
|
711
|
+
def test_uninstall_nonexistent_package() -> None:
|
|
712
|
+
"""Test remove --cl command with non-existent package should fail."""
|
|
713
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
714
|
+
original_cwd = os.getcwd()
|
|
715
|
+
try:
|
|
716
|
+
os.chdir(temp_dir)
|
|
717
|
+
|
|
718
|
+
# Create jac.toml without the package
|
|
719
|
+
_create_jac_toml(temp_dir)
|
|
720
|
+
|
|
721
|
+
# Run remove --cl command with non-existent package
|
|
722
|
+
result = run(
|
|
723
|
+
["jac", "remove", "--cl", "nonexistent-package"],
|
|
724
|
+
capture_output=True,
|
|
725
|
+
text=True,
|
|
726
|
+
)
|
|
727
|
+
|
|
728
|
+
# Should fail with non-zero exit code
|
|
729
|
+
assert result.returncode != 0
|
|
730
|
+
assert "not found" in result.stderr.lower()
|
|
731
|
+
|
|
732
|
+
finally:
|
|
733
|
+
os.chdir(original_cwd)
|
|
734
|
+
|
|
735
|
+
|
|
736
|
+
def test_uninstall_without_config_toml() -> None:
|
|
737
|
+
"""Test remove --cl command when jac.toml doesn't exist."""
|
|
738
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
739
|
+
original_cwd = os.getcwd()
|
|
740
|
+
try:
|
|
741
|
+
os.chdir(temp_dir)
|
|
742
|
+
|
|
743
|
+
# Run remove --cl command without jac.toml
|
|
744
|
+
result = run(
|
|
745
|
+
["jac", "remove", "--cl", "lodash"],
|
|
746
|
+
capture_output=True,
|
|
747
|
+
text=True,
|
|
748
|
+
)
|
|
749
|
+
|
|
750
|
+
# Should fail with non-zero exit code
|
|
751
|
+
assert result.returncode != 0
|
|
752
|
+
assert "No jac.toml found" in result.stderr
|
|
753
|
+
|
|
754
|
+
finally:
|
|
755
|
+
os.chdir(original_cwd)
|