Skip to main content

kcode_k1_daemon_lib_testkit/
lib.rs

1#![forbid(unsafe_code)]
2
3const REQUIRED_LINES: &[&str] = &[
4    "kcode-k1-access = \"0.6.2\"",
5    "kcode-k1-access-audio-classifier = \"0.1.0\"",
6    "kcode-k1-access-full-audio = \"0.10.0\"",
7    "kcode-k1-access-launch-nodes = \"0.2.2\"",
8    "kcode-k1-access-persons = \"0.3.0\"",
9    "kcode-k1-access-profiles = \"0.6.2\"",
10    "kcode-k1-audio-classification = \"0.6.0\"",
11    "kcode-k1-audio-classifier = \"0.1.1\"",
12    "kcode-k1-authority-filters = \"0.2.0\"",
13    "kcode-k1-chat-service = \"0.10.6\"",
14    "kcode-k1-codex-adapter = \"0.5.3\"",
15    "kcode-k1-codex-websearch = \"0.2.0\"",
16    "kcode-k1-daemon-http-boundary = \"0.1.1\"",
17    "kcode-k1-daemon-provider-config = \"0.1.6\"",
18    "kcode-k1-daemon-web-startup = \"0.1.1\"",
19    "kcode-k1-full-audio = \"0.4.0\"",
20    "kcode-k1-http-access-context = \"0.2.0\"",
21    "kcode-k1-http-access-profile-presentation = \"0.1.0\"",
22    "kcode-k1-http-audio = \"0.4.0\"",
23    "kcode-k1-http-chat = \"0.7.2\"",
24    "kcode-k1-http-kmap = \"0.1.0\"",
25    "kcode-k1-http-launch-nodes = \"0.3.0\"",
26    "kcode-k1-http-people = \"0.9.0\"",
27    "kcode-k1-http-persons = \"0.3.0\"",
28    "kcode-k1-ktool-set-launch-node = \"0.1.1\"",
29    "kcode-k1-ktool-social = \"0.1.1\"",
30    "kcode-k1-launch-nodes = \"0.4.0\"",
31    "kcode-k1-peering = \"0.3.1\"",
32    "kcode-k1-rust-code-ktool-service = \"0.1.0\"",
33    "kcode-k1-rust-coding = \"0.2.1\"",
34    "kcode-k1-rust-projection = \"0.2.0\"",
35    "kcode-k1-txn-ordering = \"0.5.1\"",
36    "kcode-k1-web-code-ktool-service = \"0.1.2\"",
37    "kcode-k1-web-podman = \"0.1.2\"",
38    "kcode-speaker-v3-analysis = \"0.3.5\"",
39];
40
41const OBSOLETE_LINES: &[&str] = &[
42    "kcode-k1-access = \"0.6.1\"",
43    "kcode-k1-access-full-audio = \"0.9.1\"",
44    "kcode-k1-access-full-audio = \"0.9.4\"",
45    "kcode-k1-access-launch-nodes = \"0.2.0\"",
46    "kcode-k1-audio-classification = \"0.5.9\"",
47    "kcode-k1-audio-classification = \"0.5.10\"",
48    "kcode-k1-chat-service = \"0.3.0\"",
49    "kcode-k1-chat-service = \"0.6.0\"",
50    "kcode-k1-chat-service = \"0.7.0\"",
51    "kcode-k1-chat-service = \"0.8.0\"",
52    "kcode-k1-chat-service = \"0.9.0\"",
53    "kcode-k1-chat-service = \"0.10.0\"",
54    "kcode-k1-chat-service = \"0.10.1\"",
55    "kcode-k1-chat-service = \"0.10.2\"",
56    "kcode-k1-chat-service = \"0.10.3\"",
57    "kcode-k1-chat-service = \"0.10.4\"",
58    "kcode-k1-chat-service = \"0.10.5\"",
59    "kcode-k1-codex-adapter = \"0.5.0\"",
60    "kcode-k1-codex-adapter = \"0.5.1\"",
61    "kcode-k1-codex-websearch = \"0.1.0\"",
62    "kcode-k1-daemon-http-boundary = \"0.1.0\"",
63    "kcode-k1-daemon-provider-config = \"0.1.4\"",
64    "kcode-k1-daemon-provider-config = \"0.1.5\"",
65    "kcode-k1-daemon-web-startup = \"0.1.0\"",
66    "kcode-k1-full-audio = \"0.3.7\"",
67    "kcode-k1-http-audio = \"0.3.0\"",
68    "kcode-k1-http-audio = \"0.3.1\"",
69    "kcode-k1-http-chat = \"0.2.0\"",
70    "kcode-k1-http-chat = \"0.5.0\"",
71    "kcode-k1-http-chat = \"0.6.0\"",
72    "kcode-k1-http-chat = \"0.6.1\"",
73    "kcode-k1-http-chat = \"0.7.0\"",
74    "kcode-k1-http-chat = \"0.7.1\"",
75    "kcode-k1-http-launch-nodes = \"0.2.0\"",
76    "kcode-k1-ktool-set-launch-node = \"0.1.0\"",
77    "kcode-k1-ktool-social = \"0.1.0\"",
78    "kcode-k1-launch-nodes = \"0.3.0\"",
79    "kcode-k1-peering = \"0.3.0\"",
80    "kcode-k1-web-code-ktool-service = \"0.1.1\"",
81    "kcode-k1-web-http = \"0.1.0\"",
82];
83
84const REQUIRED_SOURCE: &[&str] = &[
85    "AudioClassification::open(",
86    ".shutdown()",
87    "kcode_k1_http_audio::authenticated_routes",
88    "SocialKtools::new(",
89    "SetLaunchNodeKtool::new(",
90    "let web = open(",
91    "web.router()",
92    "web.projection()",
93    "RustCodeKtoolService::new(",
94    "K1WebCodeKtoolService::new(",
95    "K1ChatService::open_with_social_and_set_launch_node_and_rust_code_and_web_code(",
96];
97
98const PROHIBITED_SOURCE: &[&str] = &[
99    "audio-classification-v2",
100    "http_audio_artifacts",
101    "retry_fragment",
102    "artifact_route",
103    "open_router(",
104    "let chat = K1ChatService::open(",
105    "K1ChatService::open_with_social(",
106    "K1ChatService::open_with_social_and_set_launch_node(",
107];
108
109pub fn verify_manifest(manifest: &str) {
110    for required in REQUIRED_LINES {
111        assert!(
112            manifest.lines().any(|line| line == *required),
113            "missing required manifest line: {required}"
114        );
115    }
116    for obsolete in OBSOLETE_LINES {
117        assert!(
118            !manifest.lines().any(|line| line == *obsolete),
119            "obsolete manifest line: {obsolete}"
120        );
121    }
122    assert!(
123        !manifest.lines().any(|line| line
124            .trim_start()
125            .starts_with("kcode-k1-http-audio-artifacts")),
126        "artifact manifest selection"
127    );
128    assert!(
129        !manifest.lines().any(|line| line.contains(" = \"=")),
130        "manifest contains an exact internal pin"
131    );
132}
133
134pub fn verify_source(source: &str) {
135    for required in REQUIRED_SOURCE {
136        assert!(
137            source.contains(required),
138            "missing required source evidence: {required}"
139        );
140    }
141    for prohibited in PROHIBITED_SOURCE {
142        assert!(
143            !source.contains(prohibited),
144            "prohibited source token: {prohibited}"
145        );
146    }
147}
148
149#[cfg(test)]
150mod tests {
151    use super::*;
152
153    fn good_manifest() -> String {
154        REQUIRED_LINES.join("\n")
155    }
156
157    fn good_source() -> &'static str {
158        "AudioClassification::open(\nservice.shutdown()\nkcode_k1_http_audio::authenticated_routes\nSocialKtools::new(\nSetLaunchNodeKtool::new(\nlet web = open(\nweb.router()\nweb.projection()\nRustCodeKtoolService::new(\nK1WebCodeKtoolService::new(\nK1ChatService::open_with_social_and_set_launch_node_and_rust_code_and_web_code("
159    }
160
161    #[test]
162    fn accepts_current_inputs() {
163        verify_manifest(&good_manifest());
164        verify_source(good_source());
165    }
166
167    #[test]
168    fn rejects_missing_audio_requirements() {
169        for line in [
170            "kcode-k1-access-full-audio = \"0.10.0\"",
171            "kcode-k1-audio-classification = \"0.6.0\"",
172            "kcode-k1-full-audio = \"0.4.0\"",
173            "kcode-k1-http-audio = \"0.4.0\"",
174            "kcode-k1-peering = \"0.3.1\"",
175            "kcode-speaker-v3-analysis = \"0.3.5\"",
176        ] {
177            assert!(
178                std::panic::catch_unwind(|| verify_manifest(&good_manifest().replace(line, "")))
179                    .is_err()
180            );
181        }
182    }
183
184    #[test]
185    fn rejects_missing_code_composition_requirements() {
186        for line in [
187            "kcode-k1-chat-service = \"0.10.6\"",
188            "kcode-k1-daemon-web-startup = \"0.1.1\"",
189            "kcode-k1-rust-code-ktool-service = \"0.1.0\"",
190            "kcode-k1-rust-coding = \"0.2.1\"",
191            "kcode-k1-rust-projection = \"0.2.0\"",
192            "kcode-k1-web-code-ktool-service = \"0.1.2\"",
193            "kcode-k1-web-podman = \"0.1.2\"",
194        ] {
195            assert!(
196                std::panic::catch_unwind(|| verify_manifest(&good_manifest().replace(line, "")))
197                    .is_err()
198            );
199        }
200    }
201
202    #[test]
203    fn rejects_missing_source_evidence() {
204        for evidence in REQUIRED_SOURCE {
205            assert!(
206                std::panic::catch_unwind(|| verify_source(&good_source().replace(evidence, "")))
207                    .is_err()
208            );
209        }
210    }
211
212    #[test]
213    fn rejects_prohibited_source_tokens() {
214        for token in PROHIBITED_SOURCE {
215            assert!(
216                std::panic::catch_unwind(|| verify_source(&format!("{} {token}", good_source())))
217                    .is_err()
218            );
219        }
220    }
221
222    #[test]
223    fn rejects_artifact_package_selection() {
224        assert!(
225            std::panic::catch_unwind(|| verify_manifest(&format!(
226                "{}\n kcode-k1-http-audio-artifacts = \"0.4.0\"",
227                good_manifest()
228            )))
229            .is_err()
230        );
231    }
232
233    #[test]
234    fn rejects_old_audio_and_displaced_composition_lines() {
235        for line in [
236            "kcode-k1-audio-classification = \"0.5.10\"",
237            "kcode-k1-full-audio = \"0.3.7\"",
238            "kcode-k1-access-full-audio = \"0.9.4\"",
239            "kcode-k1-http-audio = \"0.3.1\"",
240            "kcode-k1-peering = \"0.3.0\"",
241            "kcode-k1-chat-service = \"0.10.5\"",
242            "kcode-k1-daemon-web-startup = \"0.1.0\"",
243            "kcode-k1-web-code-ktool-service = \"0.1.1\"",
244        ] {
245            assert!(
246                std::panic::catch_unwind(|| verify_manifest(&format!(
247                    "{}\n{line}",
248                    good_manifest()
249                )))
250                .is_err()
251            );
252        }
253    }
254
255    #[test]
256    fn full_chat_composition_does_not_match_former_names() {
257        let current =
258            "K1ChatService::open_with_social_and_set_launch_node_and_rust_code_and_web_code(";
259        assert!(!current.contains("K1ChatService::open_with_social("));
260        assert!(!current.contains("K1ChatService::open_with_social_and_set_launch_node("));
261    }
262
263    #[test]
264    fn rejects_exact_internal_pin() {
265        assert!(
266            std::panic::catch_unwind(|| verify_manifest(&format!(
267                "{}\nkcode-k1-peering = \"=0.3.1\"",
268                good_manifest()
269            )))
270            .is_err()
271        );
272    }
273
274    #[test]
275    fn rejects_unrelated_obsolete_line() {
276        assert!(
277            std::panic::catch_unwind(|| verify_manifest(&format!(
278                "{}\nkcode-k1-http-chat = \"0.7.1\"",
279                good_manifest()
280            )))
281            .is_err()
282        );
283    }
284}