Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests for requires extension parsing #6447

Draft
wants to merge 1 commit into
base: trunk
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions naga/src/front/wgsl/parse/directive/language_extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
//!
//! The focal point of this module is the [`LanguageExtension`] API.

#[cfg(test)]
use strum::IntoEnumIterator;

/// A language extension not guaranteed to be present in all environments.
///
/// WGSL spec.: <https://www.w3.org/TR/WGSL/#language-extensions-sec>
Expand Down Expand Up @@ -58,14 +61,23 @@ impl LanguageExtension {
},
}
}

#[cfg(test)]
fn iter() -> impl Iterator<Item = Self> {
let implemented = ImplementedLanguageExtension::iter().map(Self::Implemented);
let unimplemented = UnimplementedLanguageExtension::iter().map(Self::Unimplemented);
implemented.chain(unimplemented)
}
}

/// A variant of [`LanguageExtension::Implemented`].
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(test, derive(strum::EnumIter))]
pub(crate) enum ImplementedLanguageExtension {}

/// A variant of [`LanguageExtension::Unimplemented`].
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(test, derive(strum::EnumIter))]
pub(crate) enum UnimplementedLanguageExtension {
ReadOnlyAndReadWriteStorageTextures,
Packed4x8IntegerDotProduct,
Expand All @@ -83,3 +95,94 @@ impl UnimplementedLanguageExtension {
}
}
}

#[cfg(test)]
mod test {
use itertools::Itertools;
use strum::IntoEnumIterator;

use crate::front::wgsl::assert_parse_err;

use super::{ImplementedLanguageExtension, LanguageExtension};

#[test]
fn implemented() {
#[derive(Clone, Debug, strum::EnumIter)]
enum Count {
ByItself,
WithOther,
}

#[derive(Clone, Debug, strum::EnumIter)]
enum Separation {
SameLineNoSpace,
SameLine,
MultiLine,
}

#[derive(Clone, Debug, strum::EnumIter)]
enum TrailingComma {
Yes,
No,
}

#[track_caller]
fn test_requires(before: &str, idents: &[&str], ident_sep: &str, after: &str) {
let ident_list = idents.join(ident_sep);
let shader = format!("requires{before}{ident_list}{after};");
let expected_msg = "".to_string();
assert_parse_err(&shader, &expected_msg);
}

let implemented_extensions =
ImplementedLanguageExtension::iter().map(LanguageExtension::Implemented);

let iter = implemented_extensions
.clone()
.cartesian_product(Count::iter())
.cartesian_product(Separation::iter())
.cartesian_product(TrailingComma::iter());
for (((extension, count), separation), trailing_comma) in iter {
let before;
let ident_sep;
match separation {
Separation::SameLine => {
before = " ";
ident_sep = ", ";
}
Separation::SameLineNoSpace => {
before = " ";
ident_sep = ",";
}
Separation::MultiLine => {
before = "\n ";
ident_sep = ",\n ";
}
}
let after = match trailing_comma {
TrailingComma::Yes => ident_sep,
TrailingComma::No => before,
};
match count {
Count::ByItself => test_requires(before, &[extension.to_ident()], ident_sep, after),
Count::WithOther => {
for other_extension in implemented_extensions.clone() {
for list in [[extension, other_extension], [other_extension, extension]] {
let list = list.map(|e| e.to_ident());
test_requires(before, &list, ident_sep, after);
}
}
}
}
}
}

#[test]
fn unimplemented() {}

#[test]
fn unknown() {}

#[test]
fn malformed() {}
}
Loading