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.3\"",
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.0\"",
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-social = \"0.1.1\"",
29    "kcode-k1-launch-nodes = \"0.4.0\"",
30    "kcode-k1-peering = \"0.3.1\"",
31    "kcode-k1-txn-ordering = \"0.5.1\"",
32    "kcode-speaker-v3-analysis = \"0.3.5\"",
33];
34
35const OBSOLETE_LINES: &[&str] = &[
36    "kcode-k1-access = \"0.6.1\"",
37    "kcode-k1-access-full-audio = \"0.9.1\"",
38    "kcode-k1-access-full-audio = \"0.9.4\"",
39    "kcode-k1-access-launch-nodes = \"0.2.0\"",
40    "kcode-k1-audio-classification = \"0.5.9\"",
41    "kcode-k1-audio-classification = \"0.5.10\"",
42    "kcode-k1-chat-service = \"0.3.0\"",
43    "kcode-k1-chat-service = \"0.6.0\"",
44    "kcode-k1-chat-service = \"0.7.0\"",
45    "kcode-k1-chat-service = \"0.8.0\"",
46    "kcode-k1-chat-service = \"0.9.0\"",
47    "kcode-k1-chat-service = \"0.10.0\"",
48    "kcode-k1-chat-service = \"0.10.1\"",
49    "kcode-k1-chat-service = \"0.10.2\"",
50    "kcode-k1-codex-adapter = \"0.5.0\"",
51    "kcode-k1-codex-adapter = \"0.5.1\"",
52    "kcode-k1-codex-websearch = \"0.1.0\"",
53    "kcode-k1-daemon-http-boundary = \"0.1.0\"",
54    "kcode-k1-daemon-provider-config = \"0.1.4\"",
55    "kcode-k1-daemon-provider-config = \"0.1.5\"",
56    "kcode-k1-full-audio = \"0.3.7\"",
57    "kcode-k1-http-audio = \"0.3.0\"",
58    "kcode-k1-http-audio = \"0.3.1\"",
59    "kcode-k1-http-chat = \"0.2.0\"",
60    "kcode-k1-http-chat = \"0.5.0\"",
61    "kcode-k1-http-chat = \"0.6.0\"",
62    "kcode-k1-http-chat = \"0.6.1\"",
63    "kcode-k1-http-chat = \"0.7.0\"",
64    "kcode-k1-http-chat = \"0.7.1\"",
65    "kcode-k1-http-launch-nodes = \"0.2.0\"",
66    "kcode-k1-ktool-social = \"0.1.0\"",
67    "kcode-k1-launch-nodes = \"0.3.0\"",
68    "kcode-k1-peering = \"0.3.0\"",
69    "kcode-k1-web-http = \"0.1.0\"",
70];
71
72const REQUIRED_SOURCE: &[&str] = &[
73    "AudioClassification::open(",
74    ".shutdown()",
75    "kcode_k1_http_audio::authenticated_routes",
76    "SocialKtools::new(",
77    "K1ChatService::open_with_social(",
78];
79
80const PROHIBITED_SOURCE: &[&str] = &[
81    "audio-classification-v2",
82    "http_audio_artifacts",
83    "retry_fragment",
84    "artifact_route",
85    "let chat = K1ChatService::open(",
86];
87
88pub fn verify_manifest(manifest: &str) {
89    for required in REQUIRED_LINES {
90        assert!(
91            manifest.lines().any(|line| line == *required),
92            "missing required manifest line: {required}"
93        );
94    }
95    for obsolete in OBSOLETE_LINES {
96        assert!(
97            !manifest.lines().any(|line| line == *obsolete),
98            "obsolete manifest line: {obsolete}"
99        );
100    }
101    assert!(
102        !manifest.lines().any(|line| line
103            .trim_start()
104            .starts_with("kcode-k1-http-audio-artifacts")),
105        "artifact manifest selection"
106    );
107    assert!(
108        !manifest.lines().any(|line| line.contains(" = \"=")),
109        "manifest contains an exact internal pin"
110    );
111}
112
113pub fn verify_source(source: &str) {
114    for required in REQUIRED_SOURCE {
115        assert!(
116            source.contains(required),
117            "missing required source evidence: {required}"
118        );
119    }
120    for prohibited in PROHIBITED_SOURCE {
121        assert!(
122            !source.contains(prohibited),
123            "prohibited source token: {prohibited}"
124        );
125    }
126}
127
128#[cfg(test)]
129mod tests {
130    use super::*;
131
132    fn good_manifest() -> String {
133        REQUIRED_LINES.join("\n")
134    }
135
136    fn good_source() -> &'static str {
137        "AudioClassification::open(\nservice.shutdown()\nkcode_k1_http_audio::authenticated_routes\nSocialKtools::new(\nK1ChatService::open_with_social("
138    }
139
140    #[test]
141    fn accepts_current_inputs() {
142        verify_manifest(&good_manifest());
143        verify_source(good_source());
144    }
145
146    #[test]
147    fn rejects_missing_audio_requirements() {
148        for line in [
149            "kcode-k1-access-full-audio = \"0.10.0\"",
150            "kcode-k1-audio-classification = \"0.6.0\"",
151            "kcode-k1-full-audio = \"0.4.0\"",
152            "kcode-k1-http-audio = \"0.4.0\"",
153            "kcode-k1-peering = \"0.3.1\"",
154            "kcode-speaker-v3-analysis = \"0.3.5\"",
155        ] {
156            assert!(
157                std::panic::catch_unwind(|| verify_manifest(&good_manifest().replace(line, "")))
158                    .is_err()
159            );
160        }
161    }
162
163    #[test]
164    fn rejects_missing_social_manifest_requirements() {
165        for line in [
166            "kcode-k1-chat-service = \"0.10.3\"",
167            "kcode-k1-ktool-social = \"0.1.1\"",
168        ] {
169            assert!(
170                std::panic::catch_unwind(|| verify_manifest(&good_manifest().replace(line, "")))
171                    .is_err()
172            );
173        }
174    }
175
176    #[test]
177    fn rejects_missing_source_evidence() {
178        for evidence in REQUIRED_SOURCE {
179            assert!(
180                std::panic::catch_unwind(|| verify_source(&good_source().replace(evidence, "")))
181                    .is_err()
182            );
183        }
184    }
185
186    #[test]
187    fn rejects_prohibited_source_tokens() {
188        for token in PROHIBITED_SOURCE {
189            assert!(
190                std::panic::catch_unwind(|| verify_source(&format!("{} {token}", good_source())))
191                    .is_err()
192            );
193        }
194    }
195
196    #[test]
197    fn rejects_artifact_package_selection() {
198        assert!(
199            std::panic::catch_unwind(|| verify_manifest(&format!(
200                "{}\n kcode-k1-http-audio-artifacts = \"0.4.0\"",
201                good_manifest()
202            )))
203            .is_err()
204        );
205    }
206
207    #[test]
208    fn rejects_old_audio_and_displaced_social_lines() {
209        for line in [
210            "kcode-k1-audio-classification = \"0.5.10\"",
211            "kcode-k1-full-audio = \"0.3.7\"",
212            "kcode-k1-access-full-audio = \"0.9.4\"",
213            "kcode-k1-http-audio = \"0.3.1\"",
214            "kcode-k1-peering = \"0.3.0\"",
215            "kcode-k1-chat-service = \"0.10.2\"",
216            "kcode-k1-ktool-social = \"0.1.0\"",
217        ] {
218            assert!(
219                std::panic::catch_unwind(|| verify_manifest(&format!(
220                    "{}\n{line}",
221                    good_manifest()
222                )))
223                .is_err()
224            );
225        }
226    }
227
228    #[test]
229    fn rejects_exact_internal_pin() {
230        assert!(
231            std::panic::catch_unwind(|| verify_manifest(&format!(
232                "{}\nkcode-k1-peering = \"=0.3.1\"",
233                good_manifest()
234            )))
235            .is_err()
236        );
237    }
238
239    #[test]
240    fn rejects_unrelated_obsolete_line() {
241        assert!(
242            std::panic::catch_unwind(|| verify_manifest(&format!(
243                "{}\nkcode-k1-http-chat = \"0.7.1\"",
244                good_manifest()
245            )))
246            .is_err()
247        );
248    }
249}