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