cj-tauri 0.8.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/cjpm.toml +52 -25
- package/cli/cjpm.toml +1 -1
- package/cli/src/doctor.cj +304 -0
- package/cli/src/main.cj +33 -7
- package/cli/src/project.cj +59 -1
- package/cli/src/resolve.cj +348 -304
- package/cli/src/scaffold.cj +139 -22
- package/cli/templates/ohos-pc/AppScope/app.json5 +13 -0
- package/cli/templates/ohos-pc/AppScope/resources/base/element/string.json +8 -0
- package/cli/templates/ohos-pc/AppScope/resources/base/media/background.png +0 -0
- package/cli/templates/ohos-pc/AppScope/resources/base/media/foreground.png +0 -0
- package/cli/templates/ohos-pc/AppScope/resources/base/media/layered_image.json +6 -0
- package/cli/templates/ohos-pc/README.md +79 -0
- package/cli/templates/ohos-pc/build-hap.sh +190 -0
- package/cli/templates/ohos-pc/build-profile.json5 +46 -0
- package/cli/templates/ohos-pc/entry/build-profile.json5 +26 -0
- package/cli/templates/ohos-pc/entry/cjpm.toml +43 -0
- package/cli/templates/ohos-pc/entry/hvigorfile.ts +6 -0
- package/cli/templates/ohos-pc/entry/oh-package.json5 +9 -0
- package/cli/templates/ohos-pc/entry/src/main/cangjie/ability_stage.cj +17 -0
- package/cli/templates/ohos-pc/entry/src/main/cangjie/app_host.cj +94 -0
- package/cli/templates/ohos-pc/entry/src/main/cangjie/index.cj +167 -0
- package/cli/templates/ohos-pc/entry/src/main/cangjie/main_ability.cj +139 -0
- package/cli/templates/ohos-pc/entry/src/main/module.json5 +49 -0
- package/cli/templates/ohos-pc/entry/src/main/resources/base/element/color.json +8 -0
- package/cli/templates/ohos-pc/entry/src/main/resources/base/element/string.json +16 -0
- package/cli/templates/ohos-pc/entry/src/main/resources/base/media/background.png +0 -0
- package/cli/templates/ohos-pc/entry/src/main/resources/base/media/foreground.png +0 -0
- package/cli/templates/ohos-pc/entry/src/main/resources/base/media/layered_image.json +6 -0
- package/cli/templates/ohos-pc/entry/src/main/resources/base/media/startIcon.png +0 -0
- package/cli/templates/ohos-pc/entry/src/main/resources/base/profile/main_pages.json +2 -0
- package/cli/templates/ohos-pc/entry/src/main/resources/rawfile/capabilities.json +6 -0
- package/cli/templates/ohos-pc/entry/src/main/resources/rawfile/index.html +92 -0
- package/cli/templates/ohos-pc/hvigor/hvigor-config.json5 +5 -0
- package/cli/templates/ohos-pc/hvigorfile.ts +6 -0
- package/cli/templates/ohos-pc/oh-package.json5 +10 -0
- package/native/build_linux.sh +30 -2
- package/native/build_win.bat +62 -61
- package/native/core/bridge_core.c +1626 -0
- package/native/{bridge_core.h → core/bridge_core.h} +246 -6
- package/native/platforms/harmonyos/README.md +106 -0
- package/native/platforms/linux/bridge_linux.c +2485 -0
- package/native/platforms/windows/bridge_win.c +3248 -0
- package/native/tests/test_bridge_core.c +528 -1
- package/package.json +12 -3
- package/prebuilt/win32-x64/cj-tauri.exe +0 -0
- package/src/api_system.cj +10 -2
- package/src/app.cj +248 -85
- package/src/arkweb_proxy.cj +56 -0
- package/src/arkweb_script.cj +154 -0
- package/src/capability.cj +140 -0
- package/src/clipboard_bridge.cj +55 -0
- package/src/dragdrop.cj +26 -0
- package/src/embedded_assets.cj +98 -0
- package/src/hexutil.cj +53 -0
- package/src/host.cj +197 -26
- package/src/host_arkweb.cj +740 -0
- package/src/host_factory.cj +48 -0
- package/src/host_webkit.cj +202 -26
- package/src/host_webview2.cj +176 -3
- package/src/hotkey.cj +66 -0
- package/src/ipc_hub.cj +49 -0
- package/src/ipc_message.cj +2 -1
- package/src/jsutil.cj +33 -0
- package/src/log_bridge.cj +107 -0
- package/src/logging.cj +127 -0
- package/src/menu.cj +197 -196
- package/src/plugin.cj +40 -0
- package/src/plugins/clipboard/plugin_clipboard.cj +144 -0
- package/src/{plugin_dialog.cj → plugins/dialog/plugin_dialog.cj} +74 -17
- package/src/plugins/fs/plugin_fs.cj +194 -0
- package/src/plugins/http/plugin_http.cj +459 -0
- package/src/plugins/log/plugin_log.cj +105 -0
- package/src/{plugin_menu.cj → plugins/menu/plugin_menu.cj} +4 -2
- package/src/plugins/mqtt/mqtt_codec.cj +661 -0
- package/src/plugins/mqtt/plugin_mqtt.cj +1446 -0
- package/src/plugins/notification/plugin_notification.cj +146 -0
- package/src/plugins/plugins.cj +5 -0
- package/src/plugins/redis/plugin_redis.cj +2409 -0
- package/src/plugins/redis/redis_codec.cj +556 -0
- package/src/{plugin_serial.cj → plugins/serial/plugin_serial.cj} +442 -489
- package/src/{serial_bridge.cj → plugins/serial/serial_bridge.cj} +185 -184
- package/src/{plugin_shell.cj → plugins/shell/plugin_shell.cj} +230 -228
- package/src/plugins/sqlite/plugin_sqlite.cj +697 -0
- package/src/plugins/sqlite/sqlite_ffi.cj +206 -0
- package/src/plugins/store/plugin_store.cj +287 -0
- package/src/plugins/ws/plugin_ws.cj +470 -0
- package/src/process_hidden.cj +174 -0
- package/src/scope.cj +391 -0
- package/src/shell_event.cj +69 -68
- package/src/tests/capability_test.cj +53 -0
- package/src/tests/fake_host.cj +85 -20
- package/src/tests/ipc_hub_test.cj +13 -0
- package/src/tests/jsutil_test.cj +62 -0
- package/src/tests/logging_test.cj +62 -0
- package/src/tests/mqtt_codec_test.cj +405 -0
- package/src/tests/plugin_clipboard_test.cj +222 -0
- package/src/tests/plugin_dialog_test.cj +98 -4
- package/src/tests/plugin_http_test.cj +124 -0
- package/src/tests/plugin_menu_test.cj +1 -0
- package/src/tests/plugin_notification_test.cj +205 -0
- package/src/tests/plugin_serial_test.cj +269 -267
- package/src/tests/plugin_shell_test.cj +189 -188
- package/src/tests/plugin_sqlite_test.cj +230 -0
- package/src/tests/plugin_store_test.cj +260 -0
- package/src/tests/plugin_test.cj +542 -524
- package/src/tests/plugin_ws_test.cj +40 -0
- package/src/tests/process_hidden_test.cj +129 -0
- package/src/tests/redis_codec_test.cj +396 -0
- package/src/tests/scope_test.cj +350 -0
- package/src/tests/shell_event_test.cj +0 -1
- package/src/tests/system_host_test.cj +81 -79
- package/src/tests/urlutil_test.cj +53 -0
- package/src/tests/version_test.cj +75 -65
- package/src/tray.cj +90 -0
- package/src/urlutil.cj +159 -0
- package/src/version.cj +23 -2
- package/src/window.cj +51 -42
- package/native/bridge_core.c +0 -797
- package/native/bridge_linux.c +0 -1268
- package/native/bridge_win.c +0 -1633
- package/src/plugin_fs.cj +0 -118
- /package/native/{bridge_js.h → core/bridge_js.h} +0 -0
package/src/tests/fake_host.cj
CHANGED
|
@@ -25,13 +25,26 @@ class FakeHost <: WebViewHost {
|
|
|
25
25
|
// 对话框入参按「调一次记一次」存成字符串:桩不真弹窗,用例要断言的是「谁被调了、带了什么」
|
|
26
26
|
public var fileDialogArgs: String = ""
|
|
27
27
|
public var messageDialogArgs: String = ""
|
|
28
|
+
// 选目录与文件框分开记:用例要断言「走的是目录那条路」,不能与 fileDialogArgs 混为一谈
|
|
29
|
+
public var folderDialogTitle: String = ""
|
|
28
30
|
// 菜单:线路文本 / 单项状态按原样记下(桩不建真菜单,用例断言的是投下来的内容)
|
|
29
31
|
public var menuWire: String = ""
|
|
30
32
|
public var menuItemStateArgs: String = ""
|
|
33
|
+
// 标题栏副标题:桩只记最后一次文本(用例断言的是「投下来的是什么」)
|
|
34
|
+
public var titlebarSubtitleText: String = ""
|
|
35
|
+
public var dragDropArgs: String = ""
|
|
36
|
+
public var hotkeyWire: String = ""
|
|
37
|
+
public var trayWire: String = ""
|
|
38
|
+
public var windowVisibleValue: Bool = true
|
|
39
|
+
public var minimizeToTrayValue: Bool = false
|
|
31
40
|
// shell 事件回调(菜单点击等):用例可以自己调它,模拟「桥把事件送进来了」
|
|
32
41
|
public var shellHandler: (String) -> Unit = { _ => }
|
|
33
42
|
// 销毁回调:用例可以自己调它,模拟「桥通知本窗销毁了」
|
|
34
43
|
public var destroyHandler: () -> Unit = { => }
|
|
44
|
+
// 剪贴板 / 通知:写与通知按「调一次记一次」,读值可注入(默认空,用例按需设)
|
|
45
|
+
public var clipboardWritten: String = ""
|
|
46
|
+
public var clipboardReadValue: Option<String> = None<String>
|
|
47
|
+
public var notifiedArgs: String = ""
|
|
35
48
|
// 能力位:桩给「有菜单」,用例要测「平台没这个本事」时自行覆盖它
|
|
36
49
|
public var caps: Int32 = CJ_CAP_MENU
|
|
37
50
|
|
|
@@ -67,26 +80,51 @@ class FakeHost <: WebViewHost {
|
|
|
67
80
|
this.devToolsEnabled = enabled
|
|
68
81
|
}
|
|
69
82
|
|
|
70
|
-
public func openDevTools(): Unit {}
|
|
71
|
-
|
|
72
|
-
public func setMenu(wire: String): Unit {
|
|
73
|
-
this.menuWire = wire
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
public func setMenuItemState(id: String, enabled: Bool, checked: Bool): Unit {
|
|
77
|
-
this.menuItemStateArgs = "${id}|${enabled}|${checked}"
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
public func
|
|
81
|
-
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
public func
|
|
85
|
-
this.
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
public func
|
|
89
|
-
this.
|
|
83
|
+
public func openDevTools(): Unit {}
|
|
84
|
+
|
|
85
|
+
public func setMenu(wire: String): Unit {
|
|
86
|
+
this.menuWire = wire
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
public func setMenuItemState(id: String, enabled: Bool, checked: Bool): Unit {
|
|
90
|
+
this.menuItemStateArgs = "${id}|${enabled}|${checked}"
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
public func setTitlebarSubtitle(text: String): Unit {
|
|
94
|
+
this.titlebarSubtitleText = text
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
public func setDragDropPolicy(enabled: Bool, files: Bool): Unit {
|
|
98
|
+
this.dragDropArgs = "${enabled}|${files}"
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
public func setGlobalHotkeys(wire: String): Unit {
|
|
102
|
+
this.hotkeyWire = wire
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
public func setTray(wire: String): Unit {
|
|
106
|
+
this.trayWire = wire
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// 窗口可见性 / 最小化策略:桩只记最后一次设置(用例断言的是「谁被调了、带了什么」)
|
|
110
|
+
public func setWindowVisible(visible: Bool): Unit {
|
|
111
|
+
this.windowVisibleValue = visible
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
public func setMinimizeToTray(enabled: Bool): Unit {
|
|
115
|
+
this.minimizeToTrayValue = enabled
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
public func hostCapabilities(): Int32 {
|
|
119
|
+
return this.caps
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
public func setShellHandler(handler: (String) -> Unit): Unit {
|
|
123
|
+
this.shellHandler = handler
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
public func setDestroyHandler(handler: () -> Unit): Unit {
|
|
127
|
+
this.destroyHandler = handler
|
|
90
128
|
}
|
|
91
129
|
|
|
92
130
|
public func showFileDialog(save: Bool, title: String, filter: String): String {
|
|
@@ -94,11 +132,38 @@ class FakeHost <: WebViewHost {
|
|
|
94
132
|
return ""
|
|
95
133
|
}
|
|
96
134
|
|
|
135
|
+
public func showFileDialogPreset(save: Bool, title: String, filter: String,
|
|
136
|
+
defaultName: String): String {
|
|
137
|
+
// 记痕带预置名:多窗取证靠它断言「本窗拿到的是本窗预置的名字」
|
|
138
|
+
this.fileDialogArgs = "${save}|${title}|${filter}|${defaultName}"
|
|
139
|
+
return ""
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
public func showFolderDialog(title: String): String {
|
|
143
|
+
// 桩不真弹窗:记下标题即可(用例断言的是「谁被调了、带了什么」)
|
|
144
|
+
this.folderDialogTitle = title
|
|
145
|
+
return ""
|
|
146
|
+
}
|
|
147
|
+
|
|
97
148
|
public func showMessageDialog(kind: String, title: String, message: String): Bool {
|
|
98
149
|
this.messageDialogArgs = "${kind}|${title}|${message}"
|
|
99
150
|
return false
|
|
100
151
|
}
|
|
101
152
|
|
|
153
|
+
public func clipboardWriteText(text: String): Bool {
|
|
154
|
+
this.clipboardWritten = text
|
|
155
|
+
return true
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
public func clipboardReadText(): Option<String> {
|
|
159
|
+
return this.clipboardReadValue
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
public func notify(title: String, body: String): Bool {
|
|
163
|
+
this.notifiedArgs = "${title}|${body}"
|
|
164
|
+
return true
|
|
165
|
+
}
|
|
166
|
+
|
|
102
167
|
public func runJs(js: String): Unit {
|
|
103
168
|
this.jsCalls.add(js)
|
|
104
169
|
}
|
|
@@ -15,6 +15,9 @@ import std.unittest.testmacro.*
|
|
|
15
15
|
/** 固定返回 "ok" 的处理器 */
|
|
16
16
|
class OkHandler <: CommandHandler {
|
|
17
17
|
public func handle(cmd: String, args: JsonObject, ipc: IpcContext): JsonValue {
|
|
18
|
+
let _ = cmd
|
|
19
|
+
let _ = args
|
|
20
|
+
let _ = ipc
|
|
18
21
|
return JsonString("ok")
|
|
19
22
|
}
|
|
20
23
|
}
|
|
@@ -22,6 +25,9 @@ class OkHandler <: CommandHandler {
|
|
|
22
25
|
/** 抛 CommandException 的处理器(预期内的失败) */
|
|
23
26
|
class BoomHandler <: CommandHandler {
|
|
24
27
|
public func handle(cmd: String, args: JsonObject, ipc: IpcContext): JsonValue {
|
|
28
|
+
let _ = cmd
|
|
29
|
+
let _ = args
|
|
30
|
+
let _ = ipc
|
|
25
31
|
throw CommandException("boom")
|
|
26
32
|
}
|
|
27
33
|
}
|
|
@@ -29,6 +35,9 @@ class BoomHandler <: CommandHandler {
|
|
|
29
35
|
/** 抛普通异常的处理器(预期外的失败) */
|
|
30
36
|
class CrashHandler <: CommandHandler {
|
|
31
37
|
public func handle(cmd: String, args: JsonObject, ipc: IpcContext): JsonValue {
|
|
38
|
+
let _ = cmd
|
|
39
|
+
let _ = args
|
|
40
|
+
let _ = ipc
|
|
32
41
|
throw Exception("crash")
|
|
33
42
|
}
|
|
34
43
|
}
|
|
@@ -236,6 +245,9 @@ func testIpcMessageResolveKeepsPayload(): Unit {
|
|
|
236
245
|
/** 睡 300ms 再回答:模拟 `shell:exec` 这类慢命令 */
|
|
237
246
|
class SlowHandler <: CommandHandler {
|
|
238
247
|
public func handle(cmd: String, args: JsonObject, ipc: IpcContext): JsonValue {
|
|
248
|
+
let _ = cmd
|
|
249
|
+
let _ = args
|
|
250
|
+
let _ = ipc
|
|
239
251
|
sleep(Duration.millisecond * 300)
|
|
240
252
|
return JsonString("slow-ok")
|
|
241
253
|
}
|
|
@@ -304,6 +316,7 @@ func testConcurrentInvokesEachResolveExactlyOnce(): Unit {
|
|
|
304
316
|
|
|
305
317
|
/** 抛异常的监听器:验证「一个听众崩了不牵连别的听众与发送方」 */
|
|
306
318
|
func boomListener(p: JsonValue): Unit {
|
|
319
|
+
let _ = p
|
|
307
320
|
throw Exception("listener boom")
|
|
308
321
|
}
|
|
309
322
|
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
package cjTauri.tests
|
|
2
|
+
|
|
3
|
+
import cjTauri.*
|
|
4
|
+
import std.unittest.*
|
|
5
|
+
import std.unittest.testmacro.*
|
|
6
|
+
|
|
7
|
+
/*
|
|
8
|
+
* JS 字符串字面量转义的用例(鸿蒙 ArkWeb 侧的 label 注入靠它)。
|
|
9
|
+
*
|
|
10
|
+
* 为什么值得单独测:这段逻辑的失效形状是**静默的**——生成的脚本当场语法错误,
|
|
11
|
+
* 页面里 `__CJ_TAURI_LABEL__` 停在默认值 `main`,于是「按 label 过滤的事件」全部失灵,
|
|
12
|
+
* 而宿主与页面两边都不报错(AGENTS §4 同族坑)。原先它带 `@When[env == "ohos"]`
|
|
13
|
+
* 门禁、桌面 `cjpm test` 编不到,所以下沉到共享层后必须在这里锁住。
|
|
14
|
+
*
|
|
15
|
+
* 断言取**字符层面**的期望值(`\"` 就是两个字符:反斜杠 + 引号),
|
|
16
|
+
* 不整体比对拼好的脚本——那样改一改前缀就得连带改一堆测试。
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
@Test
|
|
20
|
+
func testJsStringLiteralWrapsPlainText(): Unit {
|
|
21
|
+
@Expect(jsStringLiteral("main"), "\"main\"")
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@Test
|
|
25
|
+
func testJsStringLiteralEscapesDoubleQuote(): Unit {
|
|
26
|
+
// 不转义的话 label 一变就提前收敛,脚本变成 `= "a";b";` —— 语法错误
|
|
27
|
+
@Expect(jsStringLiteral("a\"b"), "\"a\\\"b\"")
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@Test
|
|
31
|
+
func testJsStringLiteralEscapesBackslash(): Unit {
|
|
32
|
+
// Windows 风格 label / 路径片段带反斜杠:不转义会把后一个字符一起吃掉
|
|
33
|
+
@Expect(jsStringLiteral("a\\b"), "\"a\\\\b\"")
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@Test
|
|
37
|
+
func testJsStringLiteralKeepsUtf8Bytes(): Unit {
|
|
38
|
+
// 按字节扫,汉字不能被拆分或改写(三字节序列原样带过)
|
|
39
|
+
@Expect(jsStringLiteral("窗口"), "\"窗口\"")
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@Test
|
|
43
|
+
func testJsStringLiteralHandlesEmptyString(): Unit {
|
|
44
|
+
@Expect(jsStringLiteral(""), "\"\"")
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@Test
|
|
48
|
+
func testJsStringLiteralCombinesQuoteAndBackslash(): Unit {
|
|
49
|
+
// 两者相邻时最容易漏转义:期望 `"` `\` `\` `"` `\` `\` ...` 严格交错
|
|
50
|
+
@Expect(jsStringLiteral("\"\\"), "\"\\\"\\\\\"")
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@Test
|
|
54
|
+
func testJsStringLiteralLeavesOtherControlCharsAlone(): Unit {
|
|
55
|
+
// 口径是「只转义反斜杠与双引号」:制表符 / 换行不属于 label 语义,
|
|
56
|
+
// 这里断言**不**做额外加工,避免将来有人把它改成全量 JSON 编码器而悄悄改变契约
|
|
57
|
+
let tab = "\t"
|
|
58
|
+
let got = jsStringLiteral(tab)
|
|
59
|
+
// 未转义 = 长度只多出两侧引号(2 + 1 字节的制表符)
|
|
60
|
+
@Expect(got.size, 3)
|
|
61
|
+
@Expect(got.contains("\t"), true)
|
|
62
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
package cjTauri.tests
|
|
2
|
+
|
|
3
|
+
import cjTauri.*
|
|
4
|
+
import std.unittest.*
|
|
5
|
+
import std.unittest.testmacro.*
|
|
6
|
+
|
|
7
|
+
/*
|
|
8
|
+
* 日志落盘的策略层用例(RFC-003 第 5 期)。
|
|
9
|
+
*
|
|
10
|
+
* 只测**纯函数**(默认目录推导、环境变量回退、路径拼接):真的开 fd 那一段归桩自检
|
|
11
|
+
* (`native/tests/test_bridge_core.c` 的 `log file` 用例)与实机 E2E——单测里调桥的
|
|
12
|
+
* `foreign func` 会踩「子包调不了 foreign func」那条(AGENTS §4,链接期报未定义符号)。
|
|
13
|
+
*
|
|
14
|
+
* 环境变量类的用例一律用**肯定不存在**的变量名:跑测试的机器上 `CJ_TAURI_LOG` 之类
|
|
15
|
+
* 可能真的设着,拿它当「未设置」来断言就是一条会随机器飘的红线。
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/** 保证不存在的变量名(前缀统一,便于将来 grep) */
|
|
19
|
+
let ABSENT_LOG_ENV: String = "CJ_TAURI_LOG_TEST_ABSENT"
|
|
20
|
+
|
|
21
|
+
@Test
|
|
22
|
+
func testLogEnvFallsBackWhenVariableMissing(): Unit {
|
|
23
|
+
@Expect(logEnvOr(ABSENT_LOG_ENV, "dflt"), "dflt")
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@Test
|
|
27
|
+
func testLogBudgetFallsBackWhenVariableMissing(): Unit {
|
|
28
|
+
@Expect(logBudgetFromEnv(ABSENT_LOG_ENV, 7), 7)
|
|
29
|
+
// 0 与负数在调用方语义里是「不轮转」,不是「用 0 当默认」——回退值原样带回
|
|
30
|
+
@Expect(logBudgetFromEnv(ABSENT_LOG_ENV, 0), 0)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@Test
|
|
34
|
+
func testDefaultLogPathUsesAppNameAndPlatformDir(): Unit {
|
|
35
|
+
let p = defaultLogPath("music")
|
|
36
|
+
// 分隔符按平台给,所以不整体比对路径;钉的是「文件名 = 应用名」、「落在 cj-tauri 目录下」
|
|
37
|
+
@Expect(p.endsWith("music.log"), true)
|
|
38
|
+
@Expect(p.contains("cj-tauri"), true)
|
|
39
|
+
// 应用没给名字时走兜底:不能拼出没有主名的 ".log"
|
|
40
|
+
@Expect(defaultLogPath("").endsWith("app.log"), true)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@Test
|
|
44
|
+
func testDefaultLogDirIsNonEmptyAndConventional(): Unit {
|
|
45
|
+
let d = defaultLogDir()
|
|
46
|
+
@Expect(d.size > 0, true)
|
|
47
|
+
@Expect(d.contains("cj-tauri"), true)
|
|
48
|
+
// 默认预算是个能落地的值:>0 才会轮转,keep>0 才有档案可留
|
|
49
|
+
@Expect(CJ_LOG_DEFAULT_MAX_KB > 0, true)
|
|
50
|
+
@Expect(CJ_LOG_DEFAULT_KEEP > 0, true)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@Test
|
|
54
|
+
func testLogPathOrDefaultPrefersEnvOverPlatformDir(): Unit {
|
|
55
|
+
// 报障路径优先:环境变量给了路径就用它,平台惯例目录被忽略(人家不必知道目录在哪)
|
|
56
|
+
@Expect(logPathOrDefault("/tmp/from-env.log", "music"), "/tmp/from-env.log")
|
|
57
|
+
// 空串=未设置,才落平台惯例目录,文件名跟应用名走(与 logEnvOr 同口径)
|
|
58
|
+
let d = logPathOrDefault("", "music")
|
|
59
|
+
@Expect(d.endsWith("music.log"), true)
|
|
60
|
+
@Expect(d.contains("cj-tauri"), true)
|
|
61
|
+
@Expect(d == defaultLogPath("music"), true)
|
|
62
|
+
}
|