test: add some snapshot tests for export type
This commit is contained in:
		
							parent
							
								
									5cb1e23008
								
							
						
					
					
						commit
						5fc338a1eb
					
				|  | @ -38,11 +38,6 @@ impl Export { | |||
|         generator: &mut CodeGenerator, | ||||
|         modules: &CheckedModules, | ||||
|     ) -> Result<Export, blueprint::Error> { | ||||
|         let program = generator | ||||
|             .generate_raw(&func.body, &func.arguments, &module.name) | ||||
|             .to_debruijn() | ||||
|             .unwrap(); | ||||
| 
 | ||||
|         let mut definitions = Definitions::new(); | ||||
| 
 | ||||
|         let parameters = func | ||||
|  | @ -69,6 +64,11 @@ impl Export { | |||
|             }) | ||||
|             .collect::<Result<_, _>>()?; | ||||
| 
 | ||||
|         let program = generator | ||||
|             .generate_raw(&func.body, &func.arguments, &module.name) | ||||
|             .to_debruijn() | ||||
|             .unwrap(); | ||||
| 
 | ||||
|         Ok(Export { | ||||
|             name: format!("{}.{}", &module.name, &func.name), | ||||
|             doc: func.doc.clone(), | ||||
|  | @ -78,3 +78,106 @@ impl Export { | |||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use super::{CheckedModules, Export}; | ||||
|     use crate::tests::TestProject; | ||||
|     use aiken_lang::{ | ||||
|         self, | ||||
|         ast::{TraceLevel, Tracing}, | ||||
|     }; | ||||
| 
 | ||||
|     macro_rules! assert_export { | ||||
|         ($code:expr) => { | ||||
|             let mut project = TestProject::new(); | ||||
| 
 | ||||
|             let modules = CheckedModules::singleton(project.check(project.parse(indoc::indoc! { $code }))); | ||||
| 
 | ||||
|             let mut generator = project.new_generator( | ||||
|                 Tracing::All(TraceLevel::Verbose), | ||||
|             ); | ||||
| 
 | ||||
|             let (module, func) = modules | ||||
|                 .functions() | ||||
|                 .next() | ||||
|                 .expect("source code did no yield any exports"); | ||||
| 
 | ||||
|             let export = Export::from_function(func, module, &mut generator, &modules); | ||||
| 
 | ||||
|             match export { | ||||
|                 Err(e) => insta::with_settings!({ | ||||
|                     description => concat!("Code:\n\n", indoc::indoc! { $code }), | ||||
|                     omit_expression => true | ||||
|                 }, { | ||||
|                     insta::assert_debug_snapshot!(e); | ||||
|                 }), | ||||
| 
 | ||||
|                 Ok(validator) => insta::with_settings!({ | ||||
|                     description => concat!("Code:\n\n", indoc::indoc! { $code }), | ||||
|                     omit_expression => true | ||||
|                 }, { | ||||
|                     insta::assert_json_snapshot!(validator); | ||||
|                 }), | ||||
|             }; | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     fn basic_export() { | ||||
|         assert_export!( | ||||
|             r#" | ||||
|             pub fn add(a: Int, b: Int) -> Int { | ||||
|                 a + b | ||||
|             } | ||||
|             "#
 | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     fn illegal_opaque_type() { | ||||
|         assert_export!( | ||||
|             r#" | ||||
|             pub opaque type Thing { | ||||
|               a: Int | ||||
|             } | ||||
| 
 | ||||
|             pub fn add(a: Thing, b: Int) -> Int { | ||||
|                 a.a + b | ||||
|             } | ||||
|             "#
 | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     fn recursive_types() { | ||||
|         assert_export!( | ||||
|             r#" | ||||
|             pub type Foo<a> { | ||||
|               Empty | ||||
|               Bar(a, Foo<a>) | ||||
|             } | ||||
| 
 | ||||
|             pub fn add(a: Foo<Int>, b: Foo<Int>) -> Int { | ||||
|               when (a, b) is { | ||||
|                 (Empty, Empty) -> 0 | ||||
|                 (Bar(x, y), Bar(c, d)) -> x + c + add(y, d) | ||||
|                 (Empty, Bar(c, d)) -> c + add(Empty, d) | ||||
|                 (Bar(x, y), Empty) -> x + add(y, Empty) | ||||
|               } | ||||
|             } | ||||
|             "#
 | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     fn cannot_export_generics() { | ||||
|         assert_export!( | ||||
|             r#" | ||||
|             pub fn add(_a: a, _b: b) -> Bool { | ||||
|                 True | ||||
|             } | ||||
|             "#
 | ||||
|         ); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -477,6 +477,20 @@ impl CheckedModules { | |||
|         items.into_iter() | ||||
|     } | ||||
| 
 | ||||
|     pub fn functions(&self) -> impl Iterator<Item = (&CheckedModule, &TypedFunction)> { | ||||
|         let mut items = vec![]; | ||||
| 
 | ||||
|         for module in self.0.values() { | ||||
|             for some_definition in module.ast.definitions() { | ||||
|                 if let Definition::Fn(def) = some_definition { | ||||
|                     items.push((module, def)); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         items.into_iter() | ||||
|     } | ||||
| 
 | ||||
|     pub fn into_validators(self) -> impl Iterator<Item = CheckedModule> { | ||||
|         self.0 | ||||
|             .into_values() | ||||
|  |  | |||
|  | @ -0,0 +1,28 @@ | |||
| --- | ||||
| source: crates/aiken-project/src/export.rs | ||||
| description: "Code:\n\npub fn add(a: Int, b: Int) -> Int {\n    a + b\n}\n" | ||||
| --- | ||||
| { | ||||
|   "name": "test_module.add", | ||||
|   "parameters": [ | ||||
|     { | ||||
|       "title": "a", | ||||
|       "schema": { | ||||
|         "$ref": "#/definitions/Int" | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "title": "b", | ||||
|       "schema": { | ||||
|         "$ref": "#/definitions/Int" | ||||
|       } | ||||
|     } | ||||
|   ], | ||||
|   "compiledCode": "500100002322337000046eb4004dd68009", | ||||
|   "hash": "bcd6700b4dba798a7d19c5769ef3deb21423f8809594a6942860dd1f", | ||||
|   "definitions": { | ||||
|     "Int": { | ||||
|       "dataType": "integer" | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | @ -0,0 +1,24 @@ | |||
| --- | ||||
| source: crates/aiken-project/src/export.rs | ||||
| description: "Code:\n\npub fn add(_a: a, _b: b) -> Bool {\n    True\n}\n" | ||||
| --- | ||||
| Schema { | ||||
|     error: Error { | ||||
|         context: FreeTypeVariable, | ||||
|         breadcrumbs: [ | ||||
|             Var { | ||||
|                 tipo: RefCell { | ||||
|                     value: Generic { | ||||
|                         id: 33, | ||||
|                     }, | ||||
|                 }, | ||||
|                 alias: None, | ||||
|             }, | ||||
|         ], | ||||
|     }, | ||||
|     location: 11..16, | ||||
|     source_code: NamedSource { | ||||
|         name: "", | ||||
|         source: "<redacted>", | ||||
|     , | ||||
| } | ||||
|  | @ -0,0 +1,24 @@ | |||
| --- | ||||
| source: crates/aiken-project/src/export.rs | ||||
| description: "Code:\n\npub opaque type Thing {\n  a: Int\n}\n\npub fn add(a: Thing, b: Int) -> Int {\n    a.a + b\n}\n" | ||||
| --- | ||||
| Schema { | ||||
|     error: Error { | ||||
|         context: IllegalOpaqueType, | ||||
|         breadcrumbs: [ | ||||
|             App { | ||||
|                 public: true, | ||||
|                 contains_opaque: true, | ||||
|                 module: "test_module", | ||||
|                 name: "Thing", | ||||
|                 args: [], | ||||
|                 alias: None, | ||||
|             }, | ||||
|         ], | ||||
|     }, | ||||
|     location: 47..55, | ||||
|     source_code: NamedSource { | ||||
|         name: "", | ||||
|         source: "<redacted>", | ||||
|     , | ||||
| } | ||||
|  | @ -0,0 +1,52 @@ | |||
| --- | ||||
| source: crates/aiken-project/src/export.rs | ||||
| description: "Code:\n\npub type Foo<a> {\n  Empty\n  Bar(a, Foo<a>)\n}\n\npub fn add(a: Foo<Int>, b: Foo<Int>) -> Int {\n  when (a, b) is {\n    (Empty, Empty) -> 0\n    (Bar(x, y), Bar(c, d)) -> x + c + add(y, d)\n    (Empty, Bar(c, d)) -> c + add(Empty, d)\n    (Bar(x, y), Empty) -> x + add(y, Empty)\n  }\n}\n" | ||||
| --- | ||||
| { | ||||
|   "name": "test_module.add", | ||||
|   "parameters": [ | ||||
|     { | ||||
|       "title": "a", | ||||
|       "schema": { | ||||
|         "$ref": "#/definitions/test_module~1Foo$Int" | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "title": "b", | ||||
|       "schema": { | ||||
|         "$ref": "#/definitions/test_module~1Foo$Int" | ||||
|       } | ||||
|     } | ||||
|   ], | ||||
|   "compiledCode": "5901c3010000323232323222323232323253330083002300937540062a666010600460126ea801052000001001132323232533300b3004300c375400c2646464a66601c600e601e6ea80284c8cdc019b80003375a60240026600c0046024602600260206ea8028010c040c044008dd6980780098069baa006001132533300b3005300c375400c2a666016600860186ea801c4c8cdc01bad300f001330034c103d8798000300f3010001300d375400e00200226466e00dd698070009980118071807800a60103d8798000300c375400a600200244464646464a66601e601260206ea800854ccc03cc024c040dd50018a4000002002264a66601e601060206ea80084c8c8c94ccc048c02cc04cdd500309919b80337000066eb4c058004ccc02c02c008c058c05c004c050dd5003002180a180a8011bad301300130113754004002264a66601e601260206ea800854ccc03cc020c040dd500189919b80375a6026002666010010980103d8798000301330140013011375400600200226466e00dd6980900099980380398091809800a60103d879800030103754002601c004601c00266ec0008004dc3a40046e1d20003006002300600133760004002ae6955ceaab9e5742ae89", | ||||
|   "hash": "4ce96c928b3be798496fca0ec3666d15d09004115df638801715b5e8", | ||||
|   "definitions": { | ||||
|     "Int": { | ||||
|       "dataType": "integer" | ||||
|     }, | ||||
|     "test_module/Foo$Int": { | ||||
|       "title": "Foo", | ||||
|       "anyOf": [ | ||||
|         { | ||||
|           "title": "Empty", | ||||
|           "dataType": "constructor", | ||||
|           "index": 0, | ||||
|           "fields": [] | ||||
|         }, | ||||
|         { | ||||
|           "title": "Bar", | ||||
|           "dataType": "constructor", | ||||
|           "index": 1, | ||||
|           "fields": [ | ||||
|             { | ||||
|               "$ref": "#/definitions/Int" | ||||
|             }, | ||||
|             { | ||||
|               "$ref": "#/definitions/test_module~1Foo$Int" | ||||
|             } | ||||
|           ] | ||||
|         } | ||||
|       ] | ||||
|     } | ||||
|   } | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	 rvcas
						rvcas