// Copyright (c) ZeroC, Inc. use crate::test_helpers::*; use slicec::diagnostics::{Diagnostic, Error}; use slicec::grammar::*; use test_case::test_case; /// Verifies that classes can contain fields. #[test] fn can_contain_fields() { // Arrange let slice = " mode = Slice1 module Test class C { i: int32 s: string b: bool } "; // Act let ast = parse_for_ast(slice); // Assert let fields = ast.find_element::("Test::C").unwrap().fields(); assert_eq!(fields.len(), 3); assert!(matches!(fields[0].identifier(), "i")); assert!(matches!(fields[1].identifier(), "s")); assert!(matches!(fields[2].identifier(), "b")); assert!(matches!( fields[0].data_type.concrete_type(), Types::Primitive(Primitive::Int32), )); assert!(matches!( fields[1].data_type.concrete_type(), Types::Primitive(Primitive::String), )); assert!(matches!( fields[2].data_type.concrete_type(), Types::Primitive(Primitive::Bool), )); } #[test_case( " class C { c: C } "; "single class circular reference" )] #[test_case( " class C1 { c2: C2 } class C2 { c1: C1 } "; "multi class circular reference" )] fn cycles_are_allowed(cycle_string: &str) { // Arrange let slice = format!( " mode = Slice1 module Test {cycle_string} " ); // Act/Assert assert_parses(slice); } /// Verifies that classes can be empty #[test] fn can_be_empty() { // Arrange let slice = " mode = Slice1 module Test class C {} "; // Act let ast = parse_for_ast(slice); // Assert let fields = ast.find_element::("Test::C").unwrap().fields(); assert_eq!(fields.len(), 0); } #[test] fn cannot_redefine_fields() { // Arrange let slice = " mode = Slice1 module Test class C { a: int32 a: string } "; // Act let diagnostics = parse_for_diagnostics(slice); // Assert let expected = Diagnostic::new(Error::Redefinition { identifier: "a".to_string(), }) .add_note("'a' was previously defined here", None); check_diagnostics(diagnostics, [expected]); }