diff --git a/Cargo.lock b/Cargo.lock index 12e4e98b..8d41de57 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -879,7 +879,7 @@ version = "1.0.1" dependencies = [ "byteorder", "hemtt-common", - "indexmap 2.0.0", + "indexmap 2.0.1", "serde", "sha-1", ] @@ -1025,9 +1025,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +checksum = "ad227c3af19d4914570ad36d30409928b75967c298feb9ea1969db3a610bb14e" dependencies = [ "equivalent", "hashbrown 0.14.0", @@ -2177,18 +2177,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.48" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" +checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.48" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" +checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" dependencies = [ "proc-macro2", "quote", @@ -2334,7 +2334,7 @@ version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca676d9ba1a322c1b64eb8045a5ec5c0cfb0c9d08e15e9ff622589ad5221c8fe" dependencies = [ - "indexmap 2.0.0", + "indexmap 2.0.1", "serde", "serde_spanned", "toml_datetime", diff --git a/libs/common/src/workspace/path.rs b/libs/common/src/workspace/path.rs index 0d59db17..01ddeb3a 100644 --- a/libs/common/src/workspace/path.rs +++ b/libs/common/src/workspace/path.rs @@ -78,7 +78,10 @@ impl WorkspacePath { /// # Errors /// [`Error::Vfs`] if the path could not be read pub fn read_to_string(&self) -> Result { - self.path.read_to_string().map_err(Into::into) + self.path + .read_to_string() + .map(|s| s.replace('\r', "")) + .map_err(Into::into) } /// Open the file for reading diff --git a/libs/config/src/analyze/class.rs b/libs/config/src/analyze/class.rs index 4bea7a03..d8f760c8 100644 --- a/libs/config/src/analyze/class.rs +++ b/libs/config/src/analyze/class.rs @@ -1,10 +1,8 @@ -use std::collections::HashMap; - use hemtt_common::reporting::{Code, Processed}; -use crate::{Class, Ident, Property}; +use crate::Class; -use super::{codes::ce3_duplicate_property::DuplicateProperty, Analyze}; +use super::Analyze; impl Analyze for Class { fn valid(&self) -> bool { @@ -27,81 +25,10 @@ impl Analyze for Class { fn errors(&self, processed: &Processed) -> Vec> { match self { Self::External { .. } => vec![], - Self::Local { properties, .. } => { - let mut errors = properties - .iter() - .flat_map(|p| p.errors(processed)) - .collect::>(); - errors.extend(self.duplicate_properties()); - errors - } - } - } -} - -impl Class { - fn duplicate_properties(&self) -> Vec> { - match self { - Self::External { .. } => vec![], - Self::Local { properties, .. } => { - let mut errors: Vec> = Vec::new(); - let mut seen: HashMap = HashMap::new(); - let mut conflicts = HashMap::new(); - for property in properties { - if matches!( - property, - Property::Delete(_) | Property::Class(Self::External { .. }) - ) { - continue; - } - if let Some(b) = seen.iter().find(|(b, _)| b.value == property.name().value) { - if let Property::Class(a) = property { - if let Property::Class(ib) = b.1 { - errors.extend(a.duplicate_inner(ib)); - continue; - } - } - conflicts - .entry(b.0.as_str().to_string()) - .or_insert_with(|| vec![b.0.clone()]) - .push(property.name().clone()); - continue; - } - seen.insert(property.name().clone(), property); - } - for (_, conflict) in conflicts { - errors.push(Box::new(DuplicateProperty::new(conflict))); - } - errors - } - } - } - - fn duplicate_inner(&self, other: &Self) -> Vec> { - let Self::Local { properties: a, .. } = self else { - return vec![]; - }; - let Self::Local { properties: b, .. } = other else { - return vec![]; - }; - - let mut errors: Vec> = Vec::new(); - for a in a { - if let Property::Class(a) = a { - if let Some(Property::Class(b)) = - b.iter().find(|b| b.name().as_str() == a.name().as_str()) - { - errors.extend(a.duplicate_inner(b)); - continue; - } - } - if let Some(b) = b.iter().find(|b| b.name().as_str() == a.name().as_str()) { - errors.push(Box::new(DuplicateProperty::new(vec![ - b.name().clone(), - a.name().clone(), - ]))); - } + Self::Local { properties, .. } => properties + .iter() + .flat_map(|p| p.errors(processed)) + .collect::>(), } - errors } } diff --git a/libs/config/src/analyze/config.rs b/libs/config/src/analyze/config.rs index 00c0f10e..477387ed 100644 --- a/libs/config/src/analyze/config.rs +++ b/libs/config/src/analyze/config.rs @@ -2,10 +2,13 @@ use std::collections::{HashMap, HashSet}; use hemtt_common::reporting::{Code, Processed}; -use crate::{Class, Config, Property}; +use crate::{Class, Config, Ident, Property}; use super::{ - codes::{ce7_missing_parent::MissingParent, cw1_parent_case::ParentCase}, + codes::{ + ce3_duplicate_property::DuplicateProperty, ce7_missing_parent::MissingParent, + cw1_parent_case::ParentCase, + }, Analyze, }; @@ -21,7 +24,7 @@ impl Analyze for Config { .flat_map(|p| p.warnings(processed)) .collect::>(); let mut defined = HashMap::new(); - warnings.extend(external_missing_warn(&self.0, &mut defined)); + warnings.extend(external_parent_case_warn(&self.0, &mut defined)); warnings } @@ -33,6 +36,7 @@ impl Analyze for Config { .collect::>(); let mut defined = HashSet::new(); errors.extend(external_missing_error(&self.0, &mut defined)); + errors.extend(duplicate_properties(&self.0)); errors } } @@ -72,7 +76,7 @@ fn external_missing_error( errors } -fn external_missing_warn( +fn external_parent_case_warn( properties: &[Property], defined: &mut HashMap, ) -> Vec> { @@ -106,10 +110,55 @@ fn external_missing_warn( } } defined.insert(name_lower, c.clone()); - warnings.extend(external_missing_warn(properties, defined)); + warnings.extend(external_parent_case_warn(properties, defined)); } } } } warnings } + +fn duplicate_properties(properties: &[Property]) -> Vec> { + let mut seen: HashMap> = HashMap::new(); + duplicate_properties_inner("", properties, &mut seen); + let mut errors: Vec> = Vec::new(); + for (_, idents) in seen { + if idents.len() > 1 && !idents.iter().all(|(class, _)| *class) { + errors.push(Box::new(DuplicateProperty::new( + idents.into_iter().map(|(_, i)| i).collect(), + ))); + } + } + errors +} + +fn duplicate_properties_inner( + scope: &str, + properties: &[Property], + seen: &mut HashMap>, +) { + for property in properties { + match property { + Property::Class(Class::Local { + name, properties, .. + }) => { + duplicate_properties_inner( + &format!("{}.{}", scope, name.value.to_lowercase()), + properties, + seen, + ); + let entry = seen + .entry(format!("{}.{}", scope, name.value.to_lowercase())) + .or_default(); + entry.push((true, name.clone())); + } + Property::Entry { name, .. } | Property::MissingSemicolon(name, _) => { + let entry = seen + .entry(format!("{}.{}", scope, name.value.to_lowercase())) + .or_default(); + entry.push((false, name.clone())); + } + _ => (), + } + } +} diff --git a/libs/config/tests/errors.rs b/libs/config/tests/errors.rs index f542edf3..2a0e8a96 100644 --- a/libs/config/tests/errors.rs +++ b/libs/config/tests/errors.rs @@ -44,7 +44,7 @@ fn check(dir: &str) { .unwrap(); } assert_eq!( - errors.join("\n").replace('\r', "").replace(r"\u{1b}[38;5;201m─\u{1b}[0m\u{1b}[38;5;201m┬\u{1b}[0m \n \u{1b}[38;5;240m │\u{1b}[0m ", r"\u{1b}[38;5;201m┬\u{1b}[0m \n \u{1b}[38;5;240m │\u{1b}[0m"), + errors.join("\n").replace('\r', ""), String::from_utf8(expected).unwrap().replace('\r', "") ); } @@ -55,6 +55,11 @@ fn check(dir: &str) { } } -bootstrap!(simple); -bootstrap!(arrays); +bootstrap!(ce1_invalid_value); +bootstrap!(ce2_invalid_value_macro); +bootstrap!(ce3_duplicate_property_separate); +bootstrap!(ce3_duplicate_property_shadow_property); +bootstrap!(ce4_missing_semicolon); +bootstrap!(ce5_unexpected_array); +bootstrap!(ce6_expected_array); bootstrap!(ce7_missing_parent); diff --git a/libs/config/tests/errors/ce1_invalid_value/source.hpp b/libs/config/tests/errors/ce1_invalid_value/source.hpp new file mode 100644 index 00000000..8ba65e26 --- /dev/null +++ b/libs/config/tests/errors/ce1_invalid_value/source.hpp @@ -0,0 +1,3 @@ +class Test { + outer = something; +}; diff --git a/libs/config/tests/errors/ce1_invalid_value/stdout.ansi b/libs/config/tests/errors/ce1_invalid_value/stdout.ansi new file mode 100644 index 00000000..1d93a3f5 --- /dev/null +++ b/libs/config/tests/errors/ce1_invalid_value/stdout.ansi @@ -0,0 +1,9 @@ +[CE1] Error: property's value could not be parsed. + ╭─[/source.hpp:2:13] + │ + 2 │     outer = something; +  │ ────┬──── +  │ ╰────── invalid value +  │ +  │ Help: use quotes `"` around the value, or a QUOTE macro if it contains #define values +───╯ diff --git a/libs/config/tests/errors/ce2_invalid_value_macro/source.hpp b/libs/config/tests/errors/ce2_invalid_value_macro/source.hpp new file mode 100644 index 00000000..329c6d71 --- /dev/null +++ b/libs/config/tests/errors/ce2_invalid_value_macro/source.hpp @@ -0,0 +1,8 @@ +#define QUOTE(x) #x +#define PATHTO(x) \some\x +#define QPATHTO(x) QUOTE(PATHTO(x)) + +path = PATHTO(thing); +class Test { + path = PATHTO(thing); +}; diff --git a/libs/config/tests/errors/ce2_invalid_value_macro/stdout.ansi b/libs/config/tests/errors/ce2_invalid_value_macro/stdout.ansi new file mode 100644 index 00000000..31b9ed95 --- /dev/null +++ b/libs/config/tests/errors/ce2_invalid_value_macro/stdout.ansi @@ -0,0 +1,23 @@ +[CE2] Error: macro's result could not be parsed + ╭─[/source.hpp:5:8] + │ + 5 │ path = PATHTO(thing); +  │ ───┬── +  │ ╰──── invalid macro result +  │ +  │ Help: perhaps this macro has a `Q_` variant or you need `QUOTE(..)` +  │ +  │ Note: The processed output was `\some\thing` +───╯ + +[CE2] Error: macro's result could not be parsed + ╭─[/source.hpp:7:12] + │ + 7 │     path = PATHTO(thing); +  │ ───┬── +  │ ╰──── invalid macro result +  │ +  │ Help: perhaps this macro has a `Q_` variant or you need `QUOTE(..)` +  │ +  │ Note: The processed output was `\some\thing` +───╯ diff --git a/libs/config/tests/errors/ce3_duplicate_property_separate/source.hpp b/libs/config/tests/errors/ce3_duplicate_property_separate/source.hpp new file mode 100644 index 00000000..75ae66b0 --- /dev/null +++ b/libs/config/tests/errors/ce3_duplicate_property_separate/source.hpp @@ -0,0 +1,8 @@ +class Test { + class Child { + inner = "something"; + }; + class Child { + inner = "something"; + }; +}; diff --git a/libs/config/tests/errors/ce3_duplicate_property_separate/stdout.ansi b/libs/config/tests/errors/ce3_duplicate_property_separate/stdout.ansi new file mode 100644 index 00000000..67e37837 --- /dev/null +++ b/libs/config/tests/errors/ce3_duplicate_property_separate/stdout.ansi @@ -0,0 +1,11 @@ +[CE3] Error: property was defined more than once + ╭─[/source.hpp:3:9] + │ + 3 │         inner = "something"; +  │ ──┬── +  │ ╰──── first defined here +  │ + 6 │         inner = "something"; +  │ ──┬── +  │ ╰──── also defined here +───╯ diff --git a/libs/config/tests/errors/ce3_duplicate_property_shadow_property/source.hpp b/libs/config/tests/errors/ce3_duplicate_property_shadow_property/source.hpp new file mode 100644 index 00000000..177c375a --- /dev/null +++ b/libs/config/tests/errors/ce3_duplicate_property_shadow_property/source.hpp @@ -0,0 +1,6 @@ +class Test { + thing = 1; + class thing { + value = 1; + }; +}; diff --git a/libs/config/tests/errors/ce3_duplicate_property_shadow_property/stdout.ansi b/libs/config/tests/errors/ce3_duplicate_property_shadow_property/stdout.ansi new file mode 100644 index 00000000..c645231b --- /dev/null +++ b/libs/config/tests/errors/ce3_duplicate_property_shadow_property/stdout.ansi @@ -0,0 +1,10 @@ +[CE3] Error: property was defined more than once + ╭─[/source.hpp:2:5] + │ + 2 │     thing = 1; +  │ ──┬── +  │ ╰──── first defined here + 3 │     class thing { +  │ ──┬── +  │ ╰──── also defined here +───╯ diff --git a/libs/config/tests/errors/ce4_missing_semicolon/source.hpp b/libs/config/tests/errors/ce4_missing_semicolon/source.hpp new file mode 100644 index 00000000..3210288b --- /dev/null +++ b/libs/config/tests/errors/ce4_missing_semicolon/source.hpp @@ -0,0 +1,4 @@ +outer = "nosemi" +class Test { + inner = "nosemi" +}; diff --git a/libs/config/tests/errors/ce4_missing_semicolon/stdout.ansi b/libs/config/tests/errors/ce4_missing_semicolon/stdout.ansi new file mode 100644 index 00000000..8b970a00 --- /dev/null +++ b/libs/config/tests/errors/ce4_missing_semicolon/stdout.ansi @@ -0,0 +1,19 @@ +[CE4] Error: property is missing a semicolon + ╭─[/source.hpp:1:17] + │ + 1 │ outer = "nosemi" +  │ ┬ +  │ ╰── missing semicolon +  │ +  │ Help: add a semicolon `;` to the end of the property +───╯ + +[CE4] Error: property is missing a semicolon + ╭─[/source.hpp:3:21] + │ + 3 │     inner = "nosemi" +  │ ┬ +  │ ╰── missing semicolon +  │ +  │ Help: add a semicolon `;` to the end of the property +───╯ diff --git a/libs/config/tests/errors/ce5_unexpected_array/source.hpp b/libs/config/tests/errors/ce5_unexpected_array/source.hpp new file mode 100644 index 00000000..2a11cdce --- /dev/null +++ b/libs/config/tests/errors/ce5_unexpected_array/source.hpp @@ -0,0 +1 @@ +array = {1,2,3}; diff --git a/libs/config/tests/errors/ce5_unexpected_array/stdout.ansi b/libs/config/tests/errors/ce5_unexpected_array/stdout.ansi new file mode 100644 index 00000000..4a20a089 --- /dev/null +++ b/libs/config/tests/errors/ce5_unexpected_array/stdout.ansi @@ -0,0 +1,9 @@ +[CE5] Error: property was not expected to be an array + ╭─[/source.hpp:1:9] + │ + 1 │ array = {1,2,3}; +  │ ──┬── ───┬─── +  │ ╰────────────── expected `array[]` here +  │ │ +  │ ╰───── unexpected array +───╯ diff --git a/libs/config/tests/errors/arrays/source.hpp b/libs/config/tests/errors/ce6_expected_array/source.hpp similarity index 57% rename from libs/config/tests/errors/arrays/source.hpp rename to libs/config/tests/errors/ce6_expected_array/source.hpp index 0981e0f9..68b8e8b2 100644 --- a/libs/config/tests/errors/arrays/source.hpp +++ b/libs/config/tests/errors/ce6_expected_array/source.hpp @@ -1,2 +1 @@ not_array[] = "hello"; -array = {1,2,3}; diff --git a/libs/config/tests/errors/arrays/stdout.ansi b/libs/config/tests/errors/ce6_expected_array/stdout.ansi similarity index 50% rename from libs/config/tests/errors/arrays/stdout.ansi rename to libs/config/tests/errors/ce6_expected_array/stdout.ansi index b430a764..3603dfa6 100644 --- a/libs/config/tests/errors/arrays/stdout.ansi +++ b/libs/config/tests/errors/ce6_expected_array/stdout.ansi @@ -7,13 +7,3 @@  │ │  │ ╰───── expected array ───╯ - -[CE5] Error: property was not expected to be an array - ╭─[/source.hpp:2:9] - │ - 2 │ array = {1,2,3}; -  │ ──┬── ───┬─── -  │ ╰────────────── expected `array[]` here -  │ │ -  │ ╰───── unexpected array -───╯ diff --git a/libs/config/tests/errors/simple/old.ansi b/libs/config/tests/errors/simple/old.ansi deleted file mode 100644 index 100dd489..00000000 --- a/libs/config/tests/errors/simple/old.ansi +++ /dev/null @@ -1,58 +0,0 @@ -[CE1] Error: property's value could not be parsed. - ╭─[/source.hpp:6:12] - │ - 6 │     data = something; -  │ ────┬──── -  │ ╰────── invalid value -  │ -  │ Help: use quotes `"` around the value, or a QUOTE macro if it contains #define values -───╯ - -[CE2] Error: macro's result could not be parsed - ╭─[/source.hpp:7:12] - │ - 7 │     path = PATHTO(thing); -  │ ───┬── -  │ ╰──── invalid macro result -  │ -  │ Help: perhaps this macro has a `Q_` variant or you need `QUOTE(..)` -  │ -  │ Note: The processed output was `\some\thing` -───╯ - -[CE4] Error: property is missing a semicolon - ╭─[/source.hpp:8:22] - │ - 8 │     data = "something" -  │ ─┬ -  │ ╰── missing semicolon -  │ -  │ Help: add a semicolon `;` to the end of the property -───╯ - -[CE3] Error: property was defined more than once - ╭─[/source.hpp:13:9] - │ - 13 │         data = "something"; -  │ ──┬─ -  │ ╰─── first defined here -  │ - 16 │         data = "something"; -  │ ──┬─ -  │ ╰─── also defined here -────╯ - -[CE3] Error: property was defined more than once - ╭─[/source.hpp:6:5] - │ - 6 │     data = something; -  │ ──┬─ -  │ ╰─── first defined here -  │ - 8 │     data = "something" -  │ ──┬─ -  │ ╰─── also defined here - 9 │     class data { -  │ ──┬─ -  │ ╰─── also defined here -───╯ diff --git a/libs/config/tests/errors/simple/source.hpp b/libs/config/tests/errors/simple/source.hpp deleted file mode 100644 index 2b7ba874..00000000 --- a/libs/config/tests/errors/simple/source.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#define QUOTE(x) #x -#define PATHTO(x) \some\x -#define QPATHTO(x) QUOTE(PATHTO(x)) - -class Test { - data = something; - path = PATHTO(thing); - data = "nosemi" - class data { - data = "something"; - }; - class Child { - data = "something"; - }; - class Child { - data = "something"; - }; -}; diff --git a/libs/config/tests/errors/simple/stdout.ansi b/libs/config/tests/errors/simple/stdout.ansi deleted file mode 100644 index fd9f5f85..00000000 --- a/libs/config/tests/errors/simple/stdout.ansi +++ /dev/null @@ -1,58 +0,0 @@ -[CE1] Error: property's value could not be parsed. - ╭─[/source.hpp:6:12] - │ - 6 │     data = something; -  │ ────┬──── -  │ ╰────── invalid value -  │ -  │ Help: use quotes `"` around the value, or a QUOTE macro if it contains #define values -───╯ - -[CE2] Error: macro's result could not be parsed - ╭─[/source.hpp:7:12] - │ - 7 │     path = PATHTO(thing); -  │ ───┬── -  │ ╰──── invalid macro result -  │ -  │ Help: perhaps this macro has a `Q_` variant or you need `QUOTE(..)` -  │ -  │ Note: The processed output was `\some\thing` -───╯ - -[CE4] Error: property is missing a semicolon - ╭─[/source.hpp:8:20] - │ - 8 │     data = "nosemi" -  │ ┬ -  │ ╰── missing semicolon -  │ -  │ Help: add a semicolon `;` to the end of the property -───╯ - -[CE3] Error: property was defined more than once - ╭─[/source.hpp:13:9] - │ - 13 │         data = "something"; -  │ ──┬─ -  │ ╰─── first defined here -  │ - 16 │         data = "something"; -  │ ──┬─ -  │ ╰─── also defined here -────╯ - -[CE3] Error: property was defined more than once - ╭─[/source.hpp:6:5] - │ - 6 │     data = something; -  │ ──┬─ -  │ ╰─── first defined here -  │ - 8 │     data = "nosemi" -  │ ──┬─ -  │ ╰─── also defined here - 9 │     class data { -  │ ──┬─ -  │ ╰─── also defined here -───╯ diff --git a/libs/config/tests/warnings.rs b/libs/config/tests/warnings.rs new file mode 100644 index 00000000..cf8cd124 --- /dev/null +++ b/libs/config/tests/warnings.rs @@ -0,0 +1,58 @@ +use std::io::Read; + +use hemtt_preprocessor::Processor; + +const ROOT: &str = "tests/warnings/"; + +macro_rules! bootstrap { + ($dir:ident) => { + paste::paste! { + #[test] + fn []() { + check(stringify!($dir)); + } + } + }; +} + +fn check(dir: &str) { + let folder = std::path::PathBuf::from(ROOT).join(dir); + let workspace = hemtt_common::workspace::Workspace::builder() + .physical(&folder) + .finish() + .unwrap(); + let source = workspace.join("source.hpp").unwrap(); + let processed = Processor::run(&source).unwrap(); + let parsed = hemtt_config::parse(&processed); + match parsed { + Ok(config) => { + let mut expected = Vec::new(); + std::fs::File::open(folder.join("stdout.ansi")) + .unwrap() + .read_to_end(&mut expected) + .unwrap(); + let warnings = config + .warnings() + .iter() + .map(|e| e.generate_processed_report(&processed).unwrap()) + .collect::>(); + if expected.is_empty() { + std::fs::write( + folder.join("stdout.ansi"), + warnings.join("\n").replace('\r', "").as_bytes(), + ) + .unwrap(); + } + assert_eq!( + warnings.join("\n").replace('\r', ""), + String::from_utf8(expected).unwrap().replace('\r', "") + ); + } + // warnings may occur, but they should be handled, if one is not a handler should be created + Err(e) => { + panic!("{:#?}", e) + } + } +} + +bootstrap!(cw1_parent_case); diff --git a/libs/config/tests/warnings/cw1_parent_case/source.hpp b/libs/config/tests/warnings/cw1_parent_case/source.hpp new file mode 100644 index 00000000..901597a7 --- /dev/null +++ b/libs/config/tests/warnings/cw1_parent_case/source.hpp @@ -0,0 +1,4 @@ +class Imported; +class Local: imported { + value = 1; +}; diff --git a/libs/config/tests/warnings/cw1_parent_case/stdout.ansi b/libs/config/tests/warnings/cw1_parent_case/stdout.ansi new file mode 100644 index 00000000..f446b850 --- /dev/null +++ b/libs/config/tests/warnings/cw1_parent_case/stdout.ansi @@ -0,0 +1,12 @@ +[CW1] Warning: parent case does not match parent definition + ╭─[/source.hpp:2:7] + │ + 1 │ class Imported; +  │ ────┬─── +  │ ╰───── parent definition here + 2 │ class Local: imported { +  │ ────┬─── +  │ ╰───── class's parent does not match parent defintion case +  │ +  │ Help: change the parent case to match the parent definition `Imported` +───╯ diff --git a/libs/preprocessor/tests/bootstrap.rs b/libs/preprocessor/tests/bootstrap.rs index 670a575e..2a71f655 100644 --- a/libs/preprocessor/tests/bootstrap.rs +++ b/libs/preprocessor/tests/bootstrap.rs @@ -30,8 +30,8 @@ fn check(dir: &str) { .unwrap() .read_to_string() .unwrap(); - let processed = processed.as_string(); - std::fs::write(folder.join("generated.hpp"), processed).unwrap(); + let processed = processed.as_string().replace('\r', ""); + std::fs::write(folder.join("generated.hpp"), &processed).unwrap(); assert_eq!(processed, expected.replace('\r', "")); } diff --git a/libs/preprocessor/tests/errors.rs b/libs/preprocessor/tests/errors.rs index d1ba56b2..be160815 100644 --- a/libs/preprocessor/tests/errors.rs +++ b/libs/preprocessor/tests/errors.rs @@ -39,14 +39,10 @@ fn check(dir: &str) { .unwrap(); let error = e.get_code().unwrap().generate_report().unwrap(); if expected.is_empty() { - std::fs::write( - folder.join("stderr.ansi"), - error.replace('\r', "").as_bytes(), - ) - .unwrap(); + std::fs::write(folder.join("stderr.ansi"), error.replace('\r', "")).unwrap(); } assert_eq!( - error.replace('\r', "").replace(r"\u{1b}[38;5;201m─\u{1b}[0m\u{1b}[38;5;201m┬\u{1b}[0m \n \u{1b}[38;5;240m │\u{1b}[0m ", r"\u{1b}[38;5;201m┬\u{1b}[0m \n \u{1b}[38;5;240m │\u{1b}[0m"), + error.replace('\r', ""), String::from_utf8(expected).unwrap().replace('\r', "") ); } diff --git a/libs/preprocessor/tests/warnings.rs b/libs/preprocessor/tests/warnings.rs index 0f337baf..5c8ac2a9 100644 --- a/libs/preprocessor/tests/warnings.rs +++ b/libs/preprocessor/tests/warnings.rs @@ -37,14 +37,10 @@ fn check(dir: &str) { .generate_report() .unwrap(); if expected.is_empty() { - std::fs::write( - folder.join("stderr.ansi"), - warning.replace('\r', "").as_bytes(), - ) - .unwrap(); + std::fs::write(folder.join("stderr.ansi"), warning.replace('\r', "")).unwrap(); } assert_eq!( - warning.replace('\r', "").replace(r"\u{1b}[38;5;201m─\u{1b}[0m\u{1b}[38;5;201m┬\u{1b}[0m \n \u{1b}[38;5;240m │\u{1b}[0m ", r"\u{1b}[38;5;201m┬\u{1b}[0m \n \u{1b}[38;5;240m │\u{1b}[0m"), + warning.replace('\r', ""), String::from_utf8(expected).unwrap().replace('\r', "") ); }