blob: 3ae1f546d9e43d91b45c0127b40fb93c48e0fd9f [file] [log] [blame]
// Copyright 2023 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
use pw_format::macros::IntegerDisplayType;
// Used to record calls into the test generator from `generator_test_macro!`.
#[derive(Debug, PartialEq)]
pub enum TestGeneratorOps {
Finalize,
StringFragment(String),
IntegerConversion {
display_type: IntegerDisplayType,
type_width: u8,
},
StringConversion,
CharConversion,
}
// Used to record calls into the test generator from `printf_generator_test_macro!` and friends.
#[derive(Debug, PartialEq)]
pub enum PrintfTestGeneratorOps {
Finalize,
StringFragment(String),
IntegerConversion { ty: String },
StringConversion,
CharConversion,
}
#[cfg(test)]
mod tests {
use pw_format::macros::IntegerDisplayType;
use pw_format_test_macros::{
char_sub_printf_generator_test_macro, generator_test_macro,
integer_sub_printf_generator_test_macro, printf_generator_test_macro,
string_sub_printf_generator_test_macro,
};
// Create an alias to ourselves so that the proc macro can name our crate.
use crate as pw_format_test_macros_test;
use super::*;
#[test]
fn generate_calls_generator_correctly() {
assert_eq!(
generator_test_macro!("test %ld %s %c", 5, "test", 'c'),
vec![
TestGeneratorOps::StringFragment("test ".to_string()),
TestGeneratorOps::IntegerConversion {
display_type: IntegerDisplayType::Signed,
type_width: 32,
},
TestGeneratorOps::StringFragment(" ".to_string()),
TestGeneratorOps::StringConversion,
TestGeneratorOps::StringFragment(" ".to_string()),
TestGeneratorOps::CharConversion,
TestGeneratorOps::Finalize
]
);
}
#[test]
fn generate_printf_calls_generator_correctly() {
assert_eq!(
printf_generator_test_macro!("test %ld %s %c", 5, "test", 'c'),
(
// %ld gets converted to %d because they are equivalent for 32 bit
// systems.
"test %d %s %c",
vec![
PrintfTestGeneratorOps::StringFragment("test ".to_string()),
PrintfTestGeneratorOps::IntegerConversion {
ty: "i32".to_string(),
},
PrintfTestGeneratorOps::StringFragment(" ".to_string()),
PrintfTestGeneratorOps::StringConversion,
PrintfTestGeneratorOps::StringFragment(" ".to_string()),
PrintfTestGeneratorOps::CharConversion,
PrintfTestGeneratorOps::Finalize
]
)
);
}
// Test that a generator returning an overridden integer conversion specifier
// changes that and only that conversion specifier in the format string.
#[test]
fn generate_printf_substitutes_integer_conversion() {
assert_eq!(
integer_sub_printf_generator_test_macro!("test %ld %s %c", 5, "test", 'c'),
(
"test %K %s %c",
vec![
PrintfTestGeneratorOps::StringFragment("test ".to_string()),
PrintfTestGeneratorOps::IntegerConversion {
ty: "i32".to_string(),
},
PrintfTestGeneratorOps::StringFragment(" ".to_string()),
PrintfTestGeneratorOps::StringConversion,
PrintfTestGeneratorOps::StringFragment(" ".to_string()),
PrintfTestGeneratorOps::CharConversion,
PrintfTestGeneratorOps::Finalize
]
)
);
}
// Test that a generator returning an overridden string conversion specifier
// changes that and only that conversion specifier in the format string.
#[test]
fn generate_printf_substitutes_string_conversion() {
assert_eq!(
string_sub_printf_generator_test_macro!("test %ld %s %c", 5, "test", 'c'),
(
// %ld gets converted to %d because they are equivalent for 32 bit
// systems.
"test %d %K %c",
vec![
PrintfTestGeneratorOps::StringFragment("test ".to_string()),
PrintfTestGeneratorOps::IntegerConversion {
ty: "i32".to_string(),
},
PrintfTestGeneratorOps::StringFragment(" ".to_string()),
PrintfTestGeneratorOps::StringConversion,
PrintfTestGeneratorOps::StringFragment(" ".to_string()),
PrintfTestGeneratorOps::CharConversion,
PrintfTestGeneratorOps::Finalize
]
)
);
}
// Test that a generator returning an overridden character conversion specifier
// changes that and only that conversion specifier in the format string.
#[test]
fn generate_printf_substitutes_char_conversion() {
assert_eq!(
char_sub_printf_generator_test_macro!("test %ld %s %c", 5, "test", 'c'),
(
// %ld gets converted to %d because they are equivalent for 32 bit
// systems.
"test %d %s %K",
vec![
PrintfTestGeneratorOps::StringFragment("test ".to_string()),
PrintfTestGeneratorOps::IntegerConversion {
ty: "i32".to_string(),
},
PrintfTestGeneratorOps::StringFragment(" ".to_string()),
PrintfTestGeneratorOps::StringConversion,
PrintfTestGeneratorOps::StringFragment(" ".to_string()),
PrintfTestGeneratorOps::CharConversion,
PrintfTestGeneratorOps::Finalize
]
)
);
}
}