• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

TyRoXx / NonlocalityOS / 14418508058

12 Apr 2025 09:55AM UTC coverage: 77.573% (+0.4%) from 77.193%
14418508058

Pull #220

github

web-flow
Merge a800aa30b into a94a66b3d
Pull Request #220: Hello world

135 of 144 new or added lines in 3 files covered. (93.75%)

5 existing lines in 1 file now uncovered.

4130 of 5324 relevant lines covered (77.57%)

1772.18 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.39
/lambda/src/complex_expression_tests.rs
1
use crate::builtins::{BUILTINS_NAMESPACE, LAMBDA_APPLY_METHOD_NAME};
2
use crate::expressions::ReadLiteral;
3
use crate::expressions::{
4
    evaluate, Application, Expression, LambdaExpression, Object, Pointer, ReadVariable,
5
};
6
use crate::type_checking::TypeCheckedExpression;
7
use crate::types::Name;
8
use crate::types::{Interface, NamespaceId, Signature, Type, TypedExpression};
9
use astraea::storage::StoreError;
10
use astraea::storage::{store_object, LoadValue};
11
use astraea::tree::BlobDigest;
12
use astraea::{
13
    storage::{InMemoryValueStorage, StoreValue},
14
    tree::{HashedValue, Value, ValueBlob},
15
};
16
use async_trait::async_trait;
17
use std::collections::BTreeMap;
18
use std::pin::Pin;
19
use std::sync::Arc;
20

21
#[derive(Debug)]
22
pub struct FileNameObject {
23
    pub content: dogbox_tree::serialization::FileName,
24
}
25

26
impl FileNameObject {
27
    pub fn new(content: dogbox_tree::serialization::FileName) -> Self {
1✔
28
        Self { content }
29
    }
30
}
31

32
#[async_trait]
33
impl Object for FileNameObject {
34
    async fn call_method(
35
        &self,
36
        _interface: &BlobDigest,
37
        _method: &Name,
38
        _argument: &Pointer,
39
        _storage: &(dyn LoadValue + Sync),
40
        _read_variable: &Arc<ReadVariable>,
41
        _read_literal: &ReadLiteral,
42
    ) -> std::result::Result<Pointer, ()> {
43
        todo!()
44
    }
45

46
    async fn serialize(
47
        &self,
48
        _storage: &(dyn StoreValue + Sync),
49
    ) -> std::result::Result<HashedValue, StoreError> {
50
        todo!()
51
    }
52

53
    async fn serialize_to_flat_value(&self) -> Option<Arc<Value>> {
1✔
54
        match Value::from_object(&self.content) {
1✔
55
            Ok(success) => Some(Arc::new(success)),
1✔
56
            Err(_) => todo!(),
57
        }
58
    }
59
}
60

61
#[derive(Debug)]
62
pub struct SmallBytes {
63
    single_value_content: HashedValue,
64
}
65

66
impl SmallBytes {
67
    pub fn new(single_value_content: HashedValue) -> Self {
1✔
68
        Self {
69
            single_value_content,
70
        }
71
    }
72
}
73

74
#[async_trait]
75
impl Object for SmallBytes {
76
    async fn call_method(
77
        &self,
78
        _interface: &BlobDigest,
79
        _method: &Name,
80
        _argument: &Pointer,
81
        _storage: &(dyn LoadValue + Sync),
82
        _read_variable: &Arc<ReadVariable>,
83
        _read_literal: &ReadLiteral,
84
    ) -> std::result::Result<Pointer, ()> {
85
        todo!()
86
    }
87

88
    async fn serialize(
89
        &self,
90
        _storage: &(dyn StoreValue + Sync),
91
    ) -> std::result::Result<HashedValue, StoreError> {
92
        Ok(self.single_value_content.clone())
1✔
93
    }
94

NEW
95
    async fn serialize_to_flat_value(&self) -> Option<Arc<Value>> {
×
NEW
96
        Some(self.single_value_content.value().clone())
×
97
    }
98
}
99

100
#[derive(Debug)]
101
pub struct LoadedFile {
102
    interface: BlobDigest,
103
    read: Name,
104
    content: BlobDigest,
105
    storage: Arc<(dyn LoadValue + Send + Sync)>,
106
}
107

108
impl LoadedFile {
109
    pub fn new(
1✔
110
        interface: BlobDigest,
111
        read: Name,
112
        content: BlobDigest,
113
        storage: Arc<(dyn LoadValue + Send + Sync)>,
114
    ) -> Self {
115
        Self {
116
            interface,
117
            read,
118
            content,
119
            storage,
120
        }
121
    }
122
}
123

124
#[async_trait]
125
impl Object for LoadedFile {
126
    async fn call_method(
127
        &self,
128
        interface: &BlobDigest,
129
        method: &Name,
130
        _argument: &Pointer,
131
        _storage: &(dyn LoadValue + Sync),
132
        _read_variable: &Arc<ReadVariable>,
133
        _read_literal: &ReadLiteral,
134
    ) -> std::result::Result<Pointer, ()> {
135
        if &self.interface == interface {
1✔
136
            if &self.read == method {
1✔
137
                // the argument is unit, so we don't need to check it
138
                let content = self
2✔
139
                    .storage
1✔
140
                    .load_value(&self.content)
1✔
141
                    .await.unwrap(/*TODO*/);
2✔
142
                let hashed = content.hash().unwrap(/*TODO*/);
1✔
143
                let result: Arc<(dyn Object + Sync)> = Arc::new(SmallBytes::new(hashed));
1✔
144
                Ok(Pointer::Object(result))
1✔
145
            } else {
146
                todo!()
147
            }
148
        } else {
149
            todo!()
150
        }
151
    }
152

153
    async fn serialize(
154
        &self,
155
        _storage: &(dyn StoreValue + Sync),
156
    ) -> std::result::Result<HashedValue, StoreError> {
157
        todo!()
158
    }
159

NEW
160
    async fn serialize_to_flat_value(&self) -> Option<Arc<Value>> {
×
NEW
161
        None
×
162
    }
163
}
164

165
#[derive(Debug)]
166
pub struct LoadedDirectory {
167
    value_for_references: Arc<Value>,
168
    data: dogbox_tree::serialization::DirectoryTree,
169
    self_interface: BlobDigest,
170
    get: Name,
171
    file_interface: BlobDigest,
172
    read: Name,
173
    storage: Arc<(dyn LoadValue + Send + Sync)>,
174
}
175

176
impl LoadedDirectory {
177
    pub fn new(
1✔
178
        value_for_references: Arc<Value>,
179
        data: dogbox_tree::serialization::DirectoryTree,
180
        self_interface: BlobDigest,
181
        get: Name,
182
        file_interface: BlobDigest,
183
        read: Name,
184
        storage: Arc<(dyn LoadValue + Send + Sync)>,
185
    ) -> Self {
186
        Self {
187
            value_for_references,
188
            data,
189
            self_interface,
190
            get,
191
            file_interface,
192
            read,
193
            storage,
194
        }
195
    }
196
}
197

198
#[async_trait]
199
impl Object for LoadedDirectory {
200
    async fn call_method(
201
        &self,
202
        interface: &BlobDigest,
203
        method: &Name,
204
        argument: &Pointer,
205
        _storage: &(dyn LoadValue + Sync),
206
        _read_variable: &Arc<ReadVariable>,
207
        _read_literal: &ReadLiteral,
208
    ) -> std::result::Result<Pointer, ()> {
209
        if &self.self_interface == interface {
1✔
210
            if &self.get == method {
1✔
211
                let argument_value = match argument.serialize_to_flat_value().await {
2✔
212
                    Some(success) => success,
1✔
213
                    None => todo!(),
214
                };
215
                let key: dogbox_tree::serialization::FileName = match argument_value.to_object() {
2✔
216
                    Ok(success) => success,
1✔
217
                    Err(_) => todo!(),
218
                };
219
                let child = match self.data.children.get(&key) {
2✔
220
                    Some(found) => found,
1✔
221
                    None => todo!(),
222
                };
223
                match &child.content {
1✔
224
                    dogbox_tree::serialization::ReferenceIndexOrInlineContent::Indirect(
225
                        reference_index,
1✔
226
                    ) => Ok(Pointer::Object(Arc::new(LoadedFile::new(
1✔
227
                        self.file_interface,
1✔
228
                        self.read.clone(),
1✔
229
                        self.value_for_references.references()[reference_index.0 as usize],
1✔
230
                        self.storage.clone(),
1✔
231
                    )))),
NEW
232
                    dogbox_tree::serialization::ReferenceIndexOrInlineContent::Direct(_vec) => {
×
233
                        todo!()
234
                    }
235
                }
236
            } else {
237
                todo!()
238
            }
239
        } else {
240
            todo!()
241
        }
242
    }
243

244
    async fn serialize(
245
        &self,
246
        _storage: &(dyn StoreValue + Sync),
247
    ) -> std::result::Result<HashedValue, StoreError> {
248
        todo!()
249
    }
250

NEW
251
    async fn serialize_to_flat_value(&self) -> Option<Arc<Value>> {
×
NEW
252
        None
×
253
    }
254
}
255

256
#[tokio::test]
257
async fn complex_expression() {
2✔
258
    let storage = Arc::new(InMemoryValueStorage::empty());
2✔
259
    let clock = || std::time::SystemTime::UNIX_EPOCH;
4✔
260
    let directory = Arc::new(
261
        dogbox_tree_editor::OpenDirectory::create_directory(storage.clone(), clock, 1)
2✔
262
            .await
2✔
263
            .unwrap(),
2✔
264
    );
265
    let empty_file_digest = storage
3✔
266
        .store_value(&HashedValue::from(Arc::new(Value::new(
2✔
267
            ValueBlob::try_from(bytes::Bytes::new()).unwrap(),
2✔
268
            vec![],
2✔
269
        ))))
270
        .await
2✔
271
        .unwrap();
272
    let file_name = "test.txt";
2✔
273
    let open_file = directory
3✔
274
        .clone()
275
        .open_file(file_name, &empty_file_digest)
2✔
276
        .await
2✔
277
        .unwrap();
278
    let write_permission = open_file.get_write_permission();
2✔
279
    let file_content = bytes::Bytes::from_static("Hello".as_bytes());
2✔
280
    open_file
2✔
281
        .write_bytes(&write_permission, 0, file_content.clone())
2✔
282
        .await
2✔
283
        .unwrap();
284
    open_file.flush().await.unwrap();
3✔
285
    drop(open_file);
2✔
286
    let directory_status = directory.request_save().await.unwrap();
4✔
287
    assert!(directory_status.digest.is_digest_up_to_date);
288

289
    let namespace = NamespaceId([42; 16]);
2✔
290
    let directory_type_name = Name::new(namespace, "directory".to_string());
2✔
291
    let directory_type = Type::Named(directory_type_name);
2✔
292
    let lambda_parameter_name = Name::new(namespace.clone(), "arg".to_string());
2✔
293
    let read_lambda_parameter_expression = TypedExpression::new(
294
        Expression::ReadVariable(lambda_parameter_name.clone()),
2✔
295
        directory_type.clone(),
2✔
296
    );
297
    let file_name_type_name = Name::new(namespace, "file_name".to_string());
2✔
298
    let file_name_type = Type::Named(file_name_type_name);
2✔
299
    let regular_file_type_name = Name::new(namespace, "regular_file".to_string());
2✔
300
    let regular_file_type = Type::Named(regular_file_type_name.clone());
2✔
301
    let get_name = Name::new(namespace, "get".to_string());
2✔
302
    let directory_interface = Arc::new(Interface::new(BTreeMap::from([(
2✔
303
        get_name.clone(),
2✔
304
        Signature::new(file_name_type.clone(), regular_file_type.clone()),
2✔
305
    )])));
306
    let directory_interface_ref = store_object(&*storage, &*directory_interface)
3✔
307
        .await
2✔
308
        .unwrap();
309
    let file_name_value = HashedValue::from(Arc::new(
2✔
310
        Value::from_object(
2✔
311
            &dogbox_tree::serialization::FileName::try_from(file_name.to_string()).unwrap(),
2✔
312
        )
313
        .unwrap(),
2✔
314
    ));
315
    let get_expression = read_lambda_parameter_expression
2✔
316
        .apply(
317
            &directory_interface,
2✔
318
            &directory_interface_ref,
2✔
319
            get_name.clone(),
2✔
320
            TypedExpression::new(
2✔
321
                Expression::Literal(file_name_type.clone(), file_name_value),
2✔
322
                file_name_type.clone(),
2✔
323
            ),
324
        )
325
        .unwrap();
326
    let bytes_type_name = Name::new(namespace, "bytes".to_string());
2✔
327
    let bytes_type = Type::Named(bytes_type_name);
2✔
328
    let bytes_interface = Arc::new(Interface::new(BTreeMap::from([
2✔
329
        //TODO: add methods
330
    ])));
331
    let bytes_interface_ref = store_object(&*storage, &*bytes_interface).await.unwrap();
4✔
332
    let read_name = Name::new(namespace, "read".to_string());
2✔
333
    let regular_file_interface = Arc::new(Interface::new(BTreeMap::from([(
2✔
334
        read_name.clone(),
2✔
335
        Signature::new(Type::Unit, bytes_type.clone()),
2✔
336
    )])));
337
    let regular_file_interface_ref = store_object(&*storage, &*regular_file_interface)
3✔
338
        .await
2✔
339
        .unwrap();
340
    let read_expression = get_expression
2✔
341
        .apply(
342
            &regular_file_interface,
2✔
343
            &regular_file_interface_ref,
2✔
344
            read_name.clone(),
2✔
345
            TypedExpression::unit(),
2✔
346
        )
347
        .unwrap();
348
    let lambda_expression = TypedExpression::new(
349
        Expression::Lambda(Box::new(LambdaExpression::new(
2✔
350
            directory_type.clone(),
2✔
351
            lambda_parameter_name.clone(),
2✔
352
            read_expression.expression,
2✔
353
        ))),
354
        Type::Function(Box::new(Signature::new(
2✔
355
            directory_type.clone(),
2✔
356
            bytes_type.clone(),
2✔
357
        ))),
358
    );
359
    let apply_name = Name::new(BUILTINS_NAMESPACE, LAMBDA_APPLY_METHOD_NAME.to_string());
2✔
360
    let lambda_interface = Arc::new(Interface::new(BTreeMap::from([(
2✔
361
        apply_name.clone(),
2✔
362
        Signature::new(file_name_type.clone(), regular_file_type.clone()),
2✔
363
    )])));
364
    let lambda_interface_ref = store_object(&*storage, &*lambda_interface).await.unwrap();
4✔
365
    let external_parameter_name = Name::new(namespace, "external".to_string());
2✔
366
    let lambda_application = TypedExpression::new(
367
        Expression::Apply(Box::new(Application::new(
2✔
368
            lambda_expression.expression,
2✔
369
            lambda_interface_ref,
2✔
370
            apply_name.clone(),
2✔
371
            Expression::ReadVariable(external_parameter_name.clone()),
2✔
372
        ))),
373
        bytes_type.clone(),
2✔
374
    );
375

376
    {
377
        let mut program_as_string = String::new();
2✔
378
        lambda_application
2✔
379
            .expression
2✔
380
            .print(&mut program_as_string, 0)
2✔
381
            .unwrap();
382
        assert_eq!("(arg) =>\n  arg.get(literal(file_name, debd5af1f5e895bbb7fc660b5193f8e1e7bc79be1ed78aa085342a21bd5722f1941247674f4ca3d5ff7d591c5ced850bf5c666723e44d6d51ded8ec5b4049533)).read(()).apply(external)", program_as_string.as_str());
383
    }
384

385
    {
386
        let find_variable = {
2✔
387
            let directory_type = directory_type.clone();
2✔
388
            let external_parameter_name = external_parameter_name.clone();
2✔
389
            move |name: &Name| -> Option<Type> {
2✔
390
                if name == &external_parameter_name {
2✔
391
                    let directory_type = directory_type.clone();
2✔
392
                    Some(directory_type)
2✔
393
                } else {
394
                    todo!()
395
                }
396
            }
397
        };
398
        let find_interface = {
2✔
399
            let directory_type = directory_type.clone();
2✔
400
            let directory_interface_ref = directory_interface_ref.clone();
2✔
401
            let directory_interface = directory_interface.clone();
2✔
402
            move |digest: &BlobDigest,
1✔
403
                      callee: Arc<Type>|
1✔
404
                      -> Pin<
1✔
405
                    Box<dyn core::future::Future<Output = Option<Arc<Interface>>> + Send>,
1✔
406
                > {
4✔
407
                    if let Type::Function(signature) = &*callee {
5✔
408
                        // TODO: check digest
409
                        let generated_interface = Arc::new(Interface::new(BTreeMap::from([(
1✔
410
                            apply_name.clone(),
1✔
411
                           (** signature).clone(),
1✔
412
                        )])));
413
                        Box::pin(core::future::ready(Some(generated_interface)))
1✔
414
                    }
415
                    else if &directory_type == &*callee {
3✔
416
                        assert_eq!(&directory_interface_ref, digest);
417
                        Box::pin(core::future::ready(Some(directory_interface.clone())))
2✔
418
                    } else if &regular_file_type == &*callee {
2✔
419
                        assert_eq!(&regular_file_interface_ref, digest);
420
                        Box::pin(core::future::ready(Some(regular_file_interface.clone())))
2✔
421
                    } else {
422
                        assert_eq!(&bytes_type, &*callee);
423
                        assert_eq!(&bytes_interface_ref, digest);
424
                        Box::pin(core::future::ready(Some(bytes_interface.clone())))
1✔
425
                    }
426
                }
427
        };
428
        let checked =
2✔
429
            TypeCheckedExpression::check(&lambda_application, &find_variable, &find_interface)
2✔
430
                .await;
2✔
431
        assert_eq!(
432
            Ok(&lambda_application),
433
            checked.as_ref().map(|success| success.correct())
434
        );
435
    }
436

437
    let external_argument = {
2✔
438
        let loaded = storage
3✔
439
            .load_value(&directory_status.digest.last_known_digest)
2✔
440
            .await;
2✔
441
        match loaded {
2✔
442
            Some(found) => match found.hash() {
2✔
443
                Some(hashed) => {
2✔
444
                    let parsed_directory: dogbox_tree::serialization::DirectoryTree =
2✔
445
                        match postcard::from_bytes::<dogbox_tree::serialization::DirectoryTree>(
2✔
446
                            hashed.value().blob().as_slice(),
2✔
447
                        ) {
448
                            Ok(success) => success,
2✔
449
                            Err(_) => todo!(),
450
                        };
451
                    let hydrated: Arc<(dyn Object + Sync)> = Arc::new(LoadedDirectory::new(
2✔
452
                        hashed.value().clone(),
2✔
453
                        parsed_directory,
2✔
454
                        directory_interface_ref.clone(),
2✔
455
                        get_name.clone(),
2✔
456
                        regular_file_interface_ref.clone(),
2✔
457
                        read_name.clone(),
2✔
458
                        storage.clone(),
2✔
459
                    ));
460
                    Pointer::Object(hydrated)
2✔
461
                }
462
                None => todo!(),
463
            },
464
            None => todo!(),
465
        }
466
    };
467
    let read_variable: Arc<ReadVariable> = Arc::new(
468
        move |name: &Name| -> Pin<Box<dyn core::future::Future<Output = Pointer> + Send>> {
3✔
469
            if name == &external_parameter_name {
2✔
470
                let external_argument = external_argument.clone();
2✔
471
                Box::pin(async move { external_argument })
4✔
472
            } else {
473
                todo!()
1✔
474
            }
475
        },
476
    );
477
    let read_literal = move |literal_type: Type,
2✔
478
                             value: HashedValue|
1✔
479
          -> Pin<Box<dyn core::future::Future<Output = Pointer> + Send>> {
2✔
480
        assert_eq!(&file_name_type, &literal_type);
481
        let file_name: dogbox_tree::serialization::FileName =
2✔
482
            value.value().to_object().unwrap(/*TODO*/);
2✔
483
        Box::pin(async move { Pointer::Object(Arc::new(FileNameObject::new(file_name))) })
4✔
484
    };
485
    let evaluation_result = evaluate(
486
        &lambda_application.expression,
2✔
487
        &*storage,
2✔
488
        &read_variable,
2✔
489
        &read_literal,
2✔
490
    )
491
    .await
2✔
492
    .serialize(&*storage)
2✔
493
    .await
2✔
494
    .unwrap();
495
    assert_eq!(
496
        &Value::new(ValueBlob::try_from(file_content).unwrap(), Vec::new()),
497
        &**evaluation_result.value()
498
    );
499
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc